| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| node-npmtest-nyc/ | 100% | (147 / 147) | 100% | (122 / 122) | 100% | (26 / 26) | 100% | (147 / 147) | |
| node-npmtest-nyc/nyc/ | 21.05% | (64 / 304) | 1.71% | (2 / 117) | 0% | (0 / 55) | 21.55% | (64 / 297) | |
| node-npmtest-nyc/nyc/lib/ | 14.55% | (8 / 55) | 0% | (0 / 12) | 0% | (0 / 12) | 14.55% | (8 / 55) | |
| node-npmtest-nyc/nyc/node_modules/append-transform/ | 13.95% | (6 / 43) | 0% | (0 / 20) | 0% | (0 / 9) | 13.95% | (6 / 43) | |
| node-npmtest-nyc/nyc/node_modules/archy/ | 5.56% | (1 / 18) | 0% | (0 / 22) | 0% | (0 / 3) | 6.67% | (1 / 15) | |
| node-npmtest-nyc/nyc/node_modules/arr-diff/ | 26.67% | (4 / 15) | 0% | (0 / 6) | 0% | (0 / 1) | 26.67% | (4 / 15) | |
| node-npmtest-nyc/nyc/node_modules/arr-flatten/ | 18.18% | (2 / 11) | 0% | (0 / 2) | 0% | (0 / 2) | 18.18% | (2 / 11) | |
| node-npmtest-nyc/nyc/node_modules/array-unique/ | 9.09% | (1 / 11) | 0% | (0 / 4) | 0% | (0 / 1) | 9.09% | (1 / 11) | |
| node-npmtest-nyc/nyc/node_modules/arrify/ | 25% | (1 / 4) | 0% | (0 / 6) | 0% | (0 / 1) | 25% | (1 / 4) | |
| node-npmtest-nyc/nyc/node_modules/balanced-match/ | 14.29% | (5 / 35) | 0% | (0 / 26) | 0% | (0 / 3) | 15.15% | (5 / 33) | |
| node-npmtest-nyc/nyc/node_modules/brace-expansion/ | 17.27% | (19 / 110) | 0% | (0 / 55) | 0% | (0 / 13) | 17.59% | (19 / 108) | |
| node-npmtest-nyc/nyc/node_modules/braces/ | 12.15% | (22 / 181) | 0% | (0 / 101) | 0% | (0 / 21) | 12.43% | (22 / 177) | |
| node-npmtest-nyc/nyc/node_modules/builtin-modules/ | 100% | (3 / 3) | 100% | (2 / 2) | 100% | (1 / 1) | 100% | (3 / 3) | |
| node-npmtest-nyc/nyc/node_modules/caching-transform/ | 20.45% | (9 / 44) | 0% | (0 / 39) | 0% | (0 / 4) | 20.45% | (9 / 44) | |
| node-npmtest-nyc/nyc/node_modules/commondir/ | 15.38% | (2 / 13) | 0% | (0 / 8) | 0% | (0 / 3) | 15.38% | (2 / 13) | |
| node-npmtest-nyc/nyc/node_modules/concat-map/ | 20% | (2 / 10) | 25% | (1 / 4) | 0% | (0 / 2) | 22.22% | (2 / 9) | |
| node-npmtest-nyc/nyc/node_modules/convert-source-map/ | 36% | (27 / 75) | 0% | (0 / 28) | 0% | (0 / 23) | 38.57% | (27 / 70) | |
| node-npmtest-nyc/nyc/node_modules/debug-log/ | 75% | (9 / 12) | 66.67% | (4 / 6) | 33.33% | (1 / 3) | 75% | (9 / 12) | |
| node-npmtest-nyc/nyc/node_modules/default-require-extensions/ | 60% | (3 / 5) | 100% | (0 / 0) | 0% | (0 / 1) | 60% | (3 / 5) | |
| node-npmtest-nyc/nyc/node_modules/error-ex/ | 20.31% | (13 / 64) | 10% | (4 / 40) | 22.22% | (2 / 9) | 20.31% | (13 / 64) | |
| node-npmtest-nyc/nyc/node_modules/expand-brackets/ | 8.43% | (7 / 83) | 0% | (0 / 50) | 0% | (0 / 4) | 8.43% | (7 / 83) | |
| node-npmtest-nyc/nyc/node_modules/expand-range/ | 9.52% | (2 / 21) | 0% | (0 / 16) | 0% | (0 / 1) | 10.53% | (2 / 19) | |
| node-npmtest-nyc/nyc/node_modules/extglob/ | 15.25% | (9 / 59) | 0% | (0 / 30) | 0% | (0 / 7) | 15.52% | (9 / 58) | |
| node-npmtest-nyc/nyc/node_modules/filename-regex/ | 50% | (1 / 2) | 100% | (0 / 0) | 0% | (0 / 1) | 50% | (1 / 2) | |
| node-npmtest-nyc/nyc/node_modules/fill-range/ | 12.57% | (22 / 175) | 0% | (0 / 165) | 0% | (0 / 17) | 13.5% | (22 / 163) | |
| node-npmtest-nyc/nyc/node_modules/find-cache-dir/ | 26.32% | (5 / 19) | 0% | (0 / 12) | 0% | (0 / 2) | 26.32% | (5 / 19) | |
| node-npmtest-nyc/nyc/node_modules/find-up/ | 24.14% | (7 / 29) | 0% | (0 / 12) | 0% | (0 / 7) | 24.14% | (7 / 29) | |
| node-npmtest-nyc/nyc/node_modules/for-in/ | 25% | (1 / 4) | 0% | (0 / 2) | 0% | (0 / 1) | 25% | (1 / 4) | |
| node-npmtest-nyc/nyc/node_modules/for-own/ | 50% | (3 / 6) | 0% | (0 / 2) | 0% | (0 / 2) | 50% | (3 / 6) | |
| node-npmtest-nyc/nyc/node_modules/fs.realpath/ | 19.19% | (38 / 198) | 2.65% | (3 / 113) | 0% | (0 / 21) | 20.43% | (38 / 186) | |
| node-npmtest-nyc/nyc/node_modules/glob-base/ | 19.23% | (5 / 26) | 0% | (0 / 16) | 0% | (0 / 2) | 20% | (5 / 25) | |
| node-npmtest-nyc/nyc/node_modules/glob-parent/ | 42.86% | (3 / 7) | 100% | (0 / 0) | 0% | (0 / 1) | 50% | (3 / 6) | |
| node-npmtest-nyc/nyc/node_modules/glob/ | 13.15% | (114 / 867) | 0% | (0 / 579) | 0% | (0 / 72) | 13.18% | (114 / 865) | |
| node-npmtest-nyc/nyc/node_modules/graceful-fs/ | 34.73% | (157 / 452) | 13.87% | (33 / 238) | 20.45% | (18 / 88) | 36.04% | (151 / 419) | |
| node-npmtest-nyc/nyc/node_modules/has-flag/ | 100% | (6 / 6) | 50% | (4 / 8) | 100% | (1 / 1) | 100% | (6 / 6) | |
| node-npmtest-nyc/nyc/node_modules/hosted-git-info/ | 26.21% | (38 / 145) | 3.8% | (3 / 79) | 10% | (3 / 30) | 28.46% | (37 / 130) | |
| node-npmtest-nyc/nyc/node_modules/imurmurhash/ | 23.19% | (16 / 69) | 17.14% | (6 / 35) | 60% | (3 / 5) | 23.19% | (16 / 69) | |
| node-npmtest-nyc/nyc/node_modules/inflight/ | 24.14% | (7 / 29) | 0% | (0 / 4) | 0% | (0 / 5) | 25% | (7 / 28) | |
| node-npmtest-nyc/nyc/node_modules/inherits/ | 66.67% | (4 / 6) | 50% | (1 / 2) | 100% | (0 / 0) | 80% | (4 / 5) | |
| node-npmtest-nyc/nyc/node_modules/is-arrayish/ | 25% | (1 / 4) | 0% | (0 / 6) | 0% | (0 / 1) | 25% | (1 / 4) | |
| node-npmtest-nyc/nyc/node_modules/is-buffer/ | 50% | (3 / 6) | 0% | (0 / 10) | 0% | (0 / 3) | 50% | (3 / 6) | |
| node-npmtest-nyc/nyc/node_modules/is-builtin-module/ | 40% | (2 / 5) | 0% | (0 / 2) | 0% | (0 / 1) | 40% | (2 / 5) | |
| node-npmtest-nyc/nyc/node_modules/is-dotfile/ | 20% | (1 / 5) | 0% | (0 / 6) | 0% | (0 / 1) | 20% | (1 / 5) | |
| node-npmtest-nyc/nyc/node_modules/is-equal-shallow/ | 14.29% | (2 / 14) | 0% | (0 / 15) | 0% | (0 / 1) | 16.67% | (2 / 12) | |
| node-npmtest-nyc/nyc/node_modules/is-extendable/ | 50% | (1 / 2) | 0% | (0 / 4) | 0% | (0 / 1) | 50% | (1 / 2) | |
| node-npmtest-nyc/nyc/node_modules/is-extglob/ | 50% | (1 / 2) | 0% | (0 / 2) | 0% | (0 / 1) | 50% | (1 / 2) | |
| node-npmtest-nyc/nyc/node_modules/is-glob/ | 66.67% | (2 / 3) | 0% | (0 / 3) | 0% | (0 / 1) | 66.67% | (2 / 3) | |
| node-npmtest-nyc/nyc/node_modules/is-number/ | 28.57% | (2 / 7) | 0% | (0 / 6) | 0% | (0 / 1) | 28.57% | (2 / 7) | |
| node-npmtest-nyc/nyc/node_modules/is-posix-bracket/ | 50% | (1 / 2) | 0% | (0 / 2) | 0% | (0 / 1) | 50% | (1 / 2) | |
| node-npmtest-nyc/nyc/node_modules/is-primitive/ | 50% | (1 / 2) | 0% | (0 / 3) | 0% | (0 / 1) | 50% | (1 / 2) | |
| node-npmtest-nyc/nyc/node_modules/is-utf8/ | 5.88% | (1 / 17) | 0% | (0 / 57) | 0% | (0 / 1) | 5.88% | (1 / 17) | |
| node-npmtest-nyc/nyc/node_modules/isarray/ | 66.67% | (2 / 3) | 50% | (1 / 2) | 0% | (0 / 1) | 66.67% | (2 / 3) | |
| node-npmtest-nyc/nyc/node_modules/isobject/ | 66.67% | (2 / 3) | 0% | (0 / 3) | 0% | (0 / 1) | 66.67% | (2 / 3) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-coverage/ | 25% | (3 / 12) | 0% | (0 / 12) | 0% | (0 / 3) | 25% | (3 / 12) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-coverage/lib/ | 18.23% | (33 / 181) | 0% | (0 / 63) | 4% | (2 / 50) | 18.33% | (33 / 180) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-hook/ | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-hook/lib/ | 16.98% | (9 / 53) | 2.94% | (1 / 34) | 0% | (0 / 14) | 16.98% | (9 / 53) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-report/ | 60% | (3 / 5) | 100% | (0 / 0) | 0% | (0 / 2) | 60% | (3 / 5) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-report/lib/ | 28.61% | (117 / 409) | 6.45% | (10 / 155) | 13.51% | (15 / 111) | 28.75% | (117 / 407) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-report/node_modules/supports-color/ | 44.44% | (16 / 36) | 52% | (26 / 50) | 100% | (2 / 2) | 44.44% | (16 / 36) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-source-maps/ | 66.67% | (2 / 3) | 100% | (0 / 0) | 0% | (0 / 1) | 66.67% | (2 / 3) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-lib-source-maps/lib/ | 19.07% | (45 / 236) | 2.21% | (3 / 136) | 0% | (0 / 44) | 19.07% | (45 / 236) | |
| node-npmtest-nyc/nyc/node_modules/istanbul-reports/ | 40% | (2 / 5) | 0% | (0 / 2) | 0% | (0 / 1) | 40% | (2 / 5) | |
| node-npmtest-nyc/nyc/node_modules/kind-of/ | 4.92% | (3 / 61) | 0% | (0 / 69) | 0% | (0 / 1) | 4.92% | (3 / 61) | |
| node-npmtest-nyc/nyc/node_modules/load-json-file/ | 69.23% | (9 / 13) | 100% | (0 / 0) | 0% | (0 / 4) | 69.23% | (9 / 13) | |
| node-npmtest-nyc/nyc/node_modules/md5-hex/ | 16.67% | (2 / 12) | 0% | (0 / 6) | 0% | (0 / 2) | 16.67% | (2 / 12) | |
| node-npmtest-nyc/nyc/node_modules/micromatch/ | 14.88% | (25 / 168) | 0% | (0 / 116) | 0% | (0 / 15) | 15.34% | (25 / 163) | |
| node-npmtest-nyc/nyc/node_modules/micromatch/lib/ | 25.65% | (69 / 269) | 5.13% | (8 / 156) | 5.26% | (2 / 38) | 26.24% | (69 / 263) | |
| node-npmtest-nyc/nyc/node_modules/minimatch/ | 10.77% | (46 / 427) | 0% | (0 / 260) | 5.88% | (2 / 34) | 11.41% | (46 / 403) | |
| node-npmtest-nyc/nyc/node_modules/mkdirp/ | 10.34% | (6 / 58) | 0% | (0 / 42) | 0% | (0 / 6) | 11.32% | (6 / 53) | |
| node-npmtest-nyc/nyc/node_modules/normalize-package-data/lib/ | 11.31% | (37 / 327) | 0% | (0 / 268) | 3.92% | (2 / 51) | 12.54% | (37 / 295) | |
| node-npmtest-nyc/nyc/node_modules/normalize-path/ | 14.29% | (1 / 7) | 0% | (0 / 4) | 0% | (0 / 1) | 14.29% | (1 / 7) | |
| node-npmtest-nyc/nyc/node_modules/object-assign/ | 50% | (22 / 44) | 25% | (5 / 20) | 60% | (3 / 5) | 50% | (22 / 44) | |
| node-npmtest-nyc/nyc/node_modules/object.omit/ | 15% | (3 / 20) | 0% | (0 / 14) | 0% | (0 / 2) | 15.79% | (3 / 19) | |
| node-npmtest-nyc/nyc/node_modules/once/ | 34.62% | (9 / 26) | 0% | (0 / 6) | 14.29% | (1 / 7) | 36% | (9 / 25) | |
| node-npmtest-nyc/nyc/node_modules/parse-glob/ | 14.47% | (11 / 76) | 0% | (0 / 49) | 0% | (0 / 7) | 14.67% | (11 / 75) | |
| node-npmtest-nyc/nyc/node_modules/parse-json/ | 25% | (4 / 16) | 0% | (0 / 4) | 0% | (0 / 1) | 25% | (4 / 16) | |
| node-npmtest-nyc/nyc/node_modules/parse-json/vendor/ | 7.35% | (30 / 408) | 0% | (0 / 377) | 0% | (0 / 32) | 7.75% | (30 / 387) | |
| node-npmtest-nyc/nyc/node_modules/path-exists/ | 30.77% | (4 / 13) | 0% | (0 / 4) | 0% | (0 / 4) | 30.77% | (4 / 13) | |
| node-npmtest-nyc/nyc/node_modules/path-is-absolute/ | 45.45% | (5 / 11) | 12.5% | (1 / 8) | 0% | (0 / 2) | 45.45% | (5 / 11) | |
| node-npmtest-nyc/nyc/node_modules/path-parse/ | 41.18% | (14 / 34) | 3.85% | (1 / 26) | 0% | (0 / 4) | 41.18% | (14 / 34) | |
| node-npmtest-nyc/nyc/node_modules/path-type/ | 61.11% | (11 / 18) | 0% | (0 / 4) | 0% | (0 / 3) | 61.11% | (11 / 18) | |
| node-npmtest-nyc/nyc/node_modules/pify/ | 8.33% | (3 / 36) | 0% | (0 / 22) | 0% | (0 / 9) | 8.33% | (3 / 36) | |
| node-npmtest-nyc/nyc/node_modules/pinkie-promise/ | 100% | (1 / 1) | 50% | (1 / 2) | 100% | (0 / 0) | 100% | (1 / 1) | |
| node-npmtest-nyc/nyc/node_modules/pkg-dir/ | 50% | (4 / 8) | 0% | (0 / 4) | 0% | (0 / 3) | 50% | (4 / 8) | |
| node-npmtest-nyc/nyc/node_modules/preserve/ | 36.36% | (4 / 11) | 100% | (0 / 0) | 0% | (0 / 5) | 36.36% | (4 / 11) | |
| node-npmtest-nyc/nyc/node_modules/randomatic/ | 14.63% | (6 / 41) | 0% | (0 / 28) | 0% | (0 / 1) | 18.75% | (6 / 32) | |
| node-npmtest-nyc/nyc/node_modules/read-pkg-up/ | 30.77% | (4 / 13) | 0% | (0 / 4) | 0% | (0 / 4) | 30.77% | (4 / 13) | |
| node-npmtest-nyc/nyc/node_modules/read-pkg/ | 23.08% | (6 / 26) | 0% | (0 / 16) | 0% | (0 / 4) | 23.08% | (6 / 26) | |
| node-npmtest-nyc/nyc/node_modules/regex-cache/ | 34.62% | (9 / 26) | 0% | (0 / 18) | 0% | (0 / 2) | 34.62% | (9 / 26) | |
| node-npmtest-nyc/nyc/node_modules/repeat-element/ | 20% | (1 / 5) | 100% | (0 / 0) | 0% | (0 / 1) | 20% | (1 / 5) | |
| node-npmtest-nyc/nyc/node_modules/repeat-string/ | 16.67% | (4 / 24) | 0% | (0 / 16) | 0% | (0 / 1) | 18.18% | (4 / 22) | |
| node-npmtest-nyc/nyc/node_modules/require-main-filename/ | 25% | (3 / 12) | 0% | (0 / 10) | 0% | (0 / 3) | 27.27% | (3 / 11) | |
| node-npmtest-nyc/nyc/node_modules/resolve-from/ | 30% | (3 / 10) | 0% | (0 / 4) | 0% | (0 / 1) | 30% | (3 / 10) | |
| node-npmtest-nyc/nyc/node_modules/rimraf/ | 9.91% | (21 / 212) | 0% | (0 / 152) | 0% | (0 / 27) | 9.95% | (21 / 211) | |
| node-npmtest-nyc/nyc/node_modules/semver/ | 27.46% | (184 / 670) | 1.91% | (7 / 366) | 1.22% | (1 / 82) | 27.88% | (184 / 660) | |
| node-npmtest-nyc/nyc/node_modules/signal-exit/ | 42.7% | (38 / 89) | 17.65% | (6 / 34) | 8.33% | (1 / 12) | 42.7% | (38 / 89) | |
| node-npmtest-nyc/nyc/node_modules/slide/lib/ | 19.7% | (13 / 66) | 0% | (0 / 40) | 0% | (0 / 13) | 23.08% | (12 / 52) | |
| node-npmtest-nyc/nyc/node_modules/source-map/ | 100% | (3 / 3) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (3 / 3) | |
| node-npmtest-nyc/nyc/node_modules/source-map/lib/ | 14.51% | (150 / 1034) | 0.36% | (2 / 553) | 0.93% | (1 / 108) | 14.52% | (150 / 1033) | |
| node-npmtest-nyc/nyc/node_modules/spdx-correct/ | 17.57% | (13 / 74) | 0% | (0 / 22) | 0% | (0 / 27) | 17.57% | (13 / 74) | |
| node-npmtest-nyc/nyc/node_modules/spdx-expression-parse/ | 2.37% | (24 / 1014) | 1.12% | (6 / 535) | 11.76% | (4 / 34) | 2.08% | (21 / 1010) | |
| node-npmtest-nyc/nyc/node_modules/strip-bom/ | 28.57% | (2 / 7) | 0% | (0 / 11) | 0% | (0 / 1) | 28.57% | (2 / 7) | |
| node-npmtest-nyc/nyc/node_modules/test-exclude/ | 26.42% | (14 / 53) | 0% | (0 / 41) | 0% | (0 / 8) | 28.57% | (14 / 49) | |
| node-npmtest-nyc/nyc/node_modules/validate-npm-package-license/ | 25% | (7 / 28) | 0% | (0 / 16) | 0% | (0 / 3) | 25% | (7 / 28) | |
| node-npmtest-nyc/nyc/node_modules/wrappy/ | 36.84% | (7 / 19) | 40% | (4 / 10) | 25% | (1 / 4) | 38.89% | (7 / 18) | |
| node-npmtest-nyc/nyc/node_modules/write-file-atomic/ | 22.03% | (13 / 59) | 2.08% | (1 / 48) | 0% | (0 / 9) | 25% | (13 / 52) |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| example.js | 100% | (83 / 83) | 100% | (73 / 73) | 100% | (12 / 12) | 100% | (83 / 83) | |
| lib.npmtest_nyc.js | 100% | (16 / 16) | 100% | (14 / 14) | 100% | (3 / 3) | 100% | (16 / 16) | |
| test.js | 100% | (48 / 48) | 100% | (35 / 35) | 100% | (11 / 11) | 100% | (48 / 48) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 | 2 2 2 2 2 2 2 1 2 2 2 2 1 2 2 2 2 2 1 2 1 1 1 1 1 1 1 1 1 2 1 1 1 1 2 2 2 2 2 2 1 2 2 2 1 3 1 1 1 1 1 1 1 1 1 1 1 1 6 6 1 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
example.js
quickstart example
instruction
1. save this script as example.js
2. run the shell command:
$ npm install npmtest-nyc && PORT=8081 node example.js
3. play with the browser-demo on http://127.0.0.1:8081
*/
/* istanbul instrument in package npmtest_nyc */
/*jslint
bitwise: true,
browser: true,
maxerr: 8,
maxlen: 96,
node: true,
nomen: true,
regexp: true,
stupid: true
*/
(function () {
'use strict';
var local;
// run shared js-env code - pre-init
(function () {
// init local
local = {};
// init modeJs
local.modeJs = (function () {
try {
return typeof navigator.userAgent === 'string' &&
typeof document.querySelector('body') === 'object' &&
typeof XMLHttpRequest.prototype.open === 'function' &&
'browser';
} catch (errorCaughtBrowser) {
return module.exports &&
typeof process.versions.node === 'string' &&
typeof require('http').createServer === 'function' &&
'node';
}
}());
// init global
local.global = local.modeJs === 'browser'
? window
: global;
// init utility2_rollup
local = local.global.utility2_rollup || (local.modeJs === 'browser'
? local.global.utility2_npmtest_nyc
: global.utility2_moduleExports);
// export local
local.global.local = local;
}());
switch (local.modeJs) {
// post-init
// run browser js-env code - post-init
/* istanbul ignore next */
case 'browser':
local.testRunBrowser = function (event) {
Eif (!event || (event &&
event.currentTarget &&
event.currentTarget.className &&
event.currentTarget.className.includes &&
event.currentTarget.className.includes('onreset'))) {
// reset output
Array.from(
document.querySelectorAll('body > .resettable')
).forEach(function (element) {
switch (element.tagName) {
case 'INPUT':
case 'TEXTAREA':
element.value = '';
break;
default:
element.textContent = '';
}
});
}
switch (event && event.currentTarget && event.currentTarget.id) {
case 'testRunButton1':
// show tests
Eif (document.querySelector('#testReportDiv1').style.display === 'none') {
document.querySelector('#testReportDiv1').style.display = 'block';
document.querySelector('#testRunButton1').textContent =
'hide internal test';
local.modeTest = true;
local.testRunDefault(local);
// hide tests
} else {
document.querySelector('#testReportDiv1').style.display = 'none';
document.querySelector('#testRunButton1').textContent = 'run internal test';
}
break;
// custom-case
default:
break;
}
Iif (document.querySelector('#inputTextareaEval1') && (!event || (event &&
event.currentTarget &&
event.currentTarget.className &&
event.currentTarget.className.includes &&
event.currentTarget.className.includes('oneval')))) {
// try to eval input-code
try {
/*jslint evil: true*/
eval(document.querySelector('#inputTextareaEval1').value);
} catch (errorCaught) {
console.error(errorCaught.stack);
}
}
};
// log stderr and stdout to #outputTextareaStdout1
['error', 'log'].forEach(function (key) {
console[key + '_original'] = console[key];
console[key] = function () {
var element;
console[key + '_original'].apply(console, arguments);
element = document.querySelector('#outputTextareaStdout1');
Iif (!element) {
return;
}
// append text to #outputTextareaStdout1
element.value += Array.from(arguments).map(function (arg) {
return typeof arg === 'string'
? arg
: JSON.stringify(arg, null, 4);
}).join(' ') + '\n';
// scroll textarea to bottom
element.scrollTop = element.scrollHeight;
};
});
// init event-handling
['change', 'click', 'keyup'].forEach(function (event) {
Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) {
element.addEventListener(event, local.testRunBrowser);
});
});
// run tests
local.testRunBrowser();
break;
// run node js-env code - post-init
/* istanbul ignore next */
case 'node':
// export local
module.exports = local;
// require modules
local.fs = require('fs');
local.http = require('http');
local.url = require('url');
// init assets
local.assetsDict = local.assetsDict || {};
/* jslint-ignore-begin */
local.assetsDict['/assets.index.template.html'] = '\
<!doctype html>\n\
<html lang="en">\n\
<head>\n\
<meta charset="UTF-8">\n\
<meta name="viewport" content="width=device-width, initial-scale=1">\n\
<title>{{env.npm_package_name}} (v{{env.npm_package_version}})</title>\n\
<style>\n\
/*csslint\n\
box-sizing: false,\n\
universal-selector: false\n\
*/\n\
* {\n\
box-sizing: border-box;\n\
}\n\
body {\n\
background: #dde;\n\
font-family: Arial, Helvetica, sans-serif;\n\
margin: 2rem;\n\
}\n\
body > * {\n\
margin-bottom: 1rem;\n\
}\n\
.utility2FooterDiv {\n\
margin-top: 20px;\n\
text-align: center;\n\
}\n\
</style>\n\
<style>\n\
/*csslint\n\
*/\n\
textarea {\n\
font-family: monospace;\n\
height: 10rem;\n\
width: 100%;\n\
}\n\
textarea[readonly] {\n\
background: #ddd;\n\
}\n\
</style>\n\
</head>\n\
<body>\n\
<!-- utility2-comment\n\
<div id="ajaxProgressDiv1" style="background: #d00; height: 2px; left: 0; margin: 0; padding: 0; position: fixed; top: 0; transition: background 0.5s, width 1.5s; width: 25%;"></div>\n\
utility2-comment -->\n\
<h1>\n\
<!-- utility2-comment\n\
<a\n\
{{#if env.npm_package_homepage}}\n\
href="{{env.npm_package_homepage}}"\n\
{{/if env.npm_package_homepage}}\n\
target="_blank"\n\
>\n\
utility2-comment -->\n\
{{env.npm_package_name}} (v{{env.npm_package_version}})\n\
<!-- utility2-comment\n\
</a>\n\
utility2-comment -->\n\
</h1>\n\
<h3>{{env.npm_package_description}}</h3>\n\
<!-- utility2-comment\n\
<h4><a download href="assets.app.js">download standalone app</a></h4>\n\
<button class="onclick onreset" id="testRunButton1">run internal test</button><br>\n\
<div id="testReportDiv1" style="display: none;"></div>\n\
utility2-comment -->\n\
\n\
\n\
\n\
<label>stderr and stdout</label>\n\
<textarea class="resettable" id="outputTextareaStdout1" readonly></textarea>\n\
<!-- utility2-comment\n\
{{#if isRollup}}\n\
<script src="assets.app.js"></script>\n\
{{#unless isRollup}}\n\
utility2-comment -->\n\
<script src="assets.utility2.rollup.js"></script>\n\
<script src="jsonp.utility2._stateInit?callback=window.utility2._stateInit"></script>\n\
<script src="assets.npmtest_nyc.rollup.js"></script>\n\
<script src="assets.example.js"></script>\n\
<script src="assets.test.js"></script>\n\
<!-- utility2-comment\n\
{{/if isRollup}}\n\
utility2-comment -->\n\
<div class="utility2FooterDiv">\n\
[ this app was created with\n\
<a href="https://github.com/kaizhu256/node-utility2" target="_blank">utility2</a>\n\
]\n\
</div>\n\
</body>\n\
</html>\n\
';
/* jslint-ignore-end */
Iif (local.templateRender) {
local.assetsDict['/'] = local.templateRender(
local.assetsDict['/assets.index.template.html'],
{
env: local.objectSetDefault(local.env, {
npm_package_description: 'the greatest app in the world!',
npm_package_name: 'my-app',
npm_package_nameAlias: 'my_app',
npm_package_version: '0.0.1'
})
}
);
} else {
local.assetsDict['/'] = local.assetsDict['/assets.index.template.html']
.replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) {
// jslint-hack
String(match0);
switch (match1) {
case 'npm_package_description':
return 'the greatest app in the world!';
case 'npm_package_name':
return 'my-app';
case 'npm_package_nameAlias':
return 'my_app';
case 'npm_package_version':
return '0.0.1';
}
});
}
// run the cli
Eif (local.global.utility2_rollup || module !== require.main) {
break;
}
local.assetsDict['/assets.example.js'] =
local.assetsDict['/assets.example.js'] ||
local.fs.readFileSync(__filename, 'utf8');
local.assetsDict['/assets.npmtest_nyc.rollup.js'] =
local.assetsDict['/assets.npmtest_nyc.rollup.js'] ||
local.fs.readFileSync(
// buildCustomOrg-hack
local.npmtest_nyc.__dirname +
'/lib.npmtest_nyc.js',
'utf8'
).replace((/^#!/), '//');
local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || '';
// if $npm_config_timeout_exit exists,
// then exit this process after $npm_config_timeout_exit ms
if (Number(process.env.npm_config_timeout_exit)) {
setTimeout(process.exit, Number(process.env.npm_config_timeout_exit));
}
// start server
if (local.global.utility2_serverHttp1) {
break;
}
process.env.PORT = process.env.PORT || '8081';
console.error('server starting on port ' + process.env.PORT);
local.http.createServer(function (request, response) {
request.urlParsed = local.url.parse(request.url);
if (local.assetsDict[request.urlParsed.pathname] !== undefined) {
response.end(local.assetsDict[request.urlParsed.pathname]);
return;
}
response.statusCode = 404;
response.end();
}).listen(process.env.PORT);
break;
}
}());
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 2 2 2 2 2 2 2 1 2 2 2 2 1 1 1 1 | /* istanbul instrument in package npmtest_nyc */
/*jslint
bitwise: true,
browser: true,
maxerr: 8,
maxlen: 96,
node: true,
nomen: true,
regexp: true,
stupid: true
*/
(function () {
'use strict';
var local;
// run shared js-env code - pre-init
(function () {
// init local
local = {};
// init modeJs
local.modeJs = (function () {
try {
return typeof navigator.userAgent === 'string' &&
typeof document.querySelector('body') === 'object' &&
typeof XMLHttpRequest.prototype.open === 'function' &&
'browser';
} catch (errorCaughtBrowser) {
return module.exports &&
typeof process.versions.node === 'string' &&
typeof require('http').createServer === 'function' &&
'node';
}
}());
// init global
local.global = local.modeJs === 'browser'
? window
: global;
// init utility2_rollup
local = local.global.utility2_rollup || local;
// init lib
local.local = local.npmtest_nyc = local;
// init exports
if (local.modeJs === 'browser') {
local.global.utility2_npmtest_nyc = local;
} else {
module.exports = local;
module.exports.__dirname = __dirname;
module.exports.module = module;
}
}());
}());
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | 2 2 2 2 2 2 2 1 2 2 1 1 1 1 2 2 2 2 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 1 2 2 1 1 1 1 1 | /* istanbul instrument in package npmtest_nyc */
/*jslint
bitwise: true,
browser: true,
maxerr: 8,
maxlen: 96,
node: true,
nomen: true,
regexp: true,
stupid: true
*/
(function () {
'use strict';
var local;
// run shared js-env code - pre-init
(function () {
// init local
local = {};
// init modeJs
local.modeJs = (function () {
try {
return typeof navigator.userAgent === 'string' &&
typeof document.querySelector('body') === 'object' &&
typeof XMLHttpRequest.prototype.open === 'function' &&
'browser';
} catch (errorCaughtBrowser) {
return module.exports &&
typeof process.versions.node === 'string' &&
typeof require('http').createServer === 'function' &&
'node';
}
}());
// init global
local.global = local.modeJs === 'browser'
? window
: global;
switch (local.modeJs) {
// re-init local from window.local
case 'browser':
local = local.global.utility2.objectSetDefault(
local.global.utility2_rollup || local.global.local,
local.global.utility2
);
break;
// re-init local from example.js
case 'node':
local = (local.global.utility2_rollup || require('utility2'))
.requireExampleJsFromReadme();
break;
}
// export local
local.global.local = local;
}());
// run shared js-env code - function
(function () {
return;
}());
switch (local.modeJs) {
// run browser js-env code - function
case 'browser':
break;
// run node js-env code - function
case 'node':
break;
}
// run shared js-env code - post-init
(function () {
return;
}());
switch (local.modeJs) {
// run browser js-env code - post-init
case 'browser':
// run tests
local.nop(local.modeTest &&
document.querySelector('#testRunButton1') &&
document.querySelector('#testRunButton1').click());
break;
// run node js-env code - post-init
/* istanbul ignore next */
case 'node':
local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function (
options,
onError
) {
/*
* this function will test buildApidoc's default handling-behavior-behavior
*/
options = { modulePathList: module.paths };
local.buildApidoc(options, onError);
};
local.testCase_buildApp_default = local.testCase_buildApp_default || function (
options,
onError
) {
/*
* this function will test buildApp's default handling-behavior-behavior
*/
local.testCase_buildReadme_default(options, local.onErrorThrow);
local.testCase_buildLib_default(options, local.onErrorThrow);
local.testCase_buildTest_default(options, local.onErrorThrow);
options = [];
local.buildApp(options, onError);
};
local.testCase_buildLib_default = local.testCase_buildLib_default || function (
options,
onError
) {
/*
* this function will test buildLib's default handling-behavior
*/
options = {};
local.buildLib(options, onError);
};
local.testCase_buildReadme_default = local.testCase_buildReadme_default || function (
options,
onError
) {
/*
* this function will test buildReadme's default handling-behavior-behavior
*/
options = {};
local.buildReadme(options, onError);
};
local.testCase_buildTest_default = local.testCase_buildTest_default || function (
options,
onError
) {
/*
* this function will test buildTest's default handling-behavior
*/
options = {};
local.buildTest(options, onError);
};
local.testCase_webpage_default = local.testCase_webpage_default || function (
options,
onError
) {
/*
* this function will test webpage's default handling-behavior
*/
options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' };
local.browserTest(options, onError);
};
// run test-server
local.testRunServer(local);
break;
}
}());
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 21.05% | (64 / 304) | 1.71% | (2 / 117) | 0% | (0 / 55) | 21.55% | (64 / 297) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* global __coverage__ */
var arrify = require('arrify')
var debugLog = require('debug-log')('nyc')
var fs = require('fs')
var glob = require('glob')
var libCoverage = require('istanbul-lib-coverage')
var libHook = require('istanbul-lib-hook')
var libReport = require('istanbul-lib-report')
var libSourceMaps = require('istanbul-lib-source-maps')
var reports = require('istanbul-reports')
var mkdirp = require('mkdirp')
var Module = require('module')
var cachingTransform = require('caching-transform')
var path = require('path')
var rimraf = require('rimraf')
var onExit = require('signal-exit')
var resolveFrom = require('resolve-from')
var convertSourceMap = require('convert-source-map')
var md5hex = require('md5-hex')
var findCacheDir = require('find-cache-dir')
var js = require('default-require-extensions/js')
var testExclude = require('test-exclude')
var ProcessInfo
try {
ProcessInfo = require('./lib/process.covered.js')
} catch (e) {
/* istanbul ignore next */
ProcessInfo = require('./lib/process.js')
}
// bust cache whenever nyc is upgraded, this prevents
// crashers caused by instrumentation updates.
var CACHE_VERSION = require('./package.json').version
/* istanbul ignore next */
Iif (/index\.covered\.js$/.test(__filename)) {
require('./lib/self-coverage-helper')
}
function NYC (config) {
config = config || {}
this.config = config
this.subprocessBin = config.subprocessBin || path.resolve(__dirname, './bin/nyc.js')
this._tempDirectory = config.tempDirectory || './.nyc_output'
this._instrumenterLib = require(config.instrumenter || './lib/instrumenters/istanbul')
this._reportDir = config.reportDir || 'coverage'
this._sourceMap = typeof config.sourceMap === 'boolean' ? config.sourceMap : true
this._showProcessTree = config.showProcessTree || false
this._eagerInstantiation = config.eager || false
this.cwd = config.cwd || process.cwd()
this.reporter = arrify(config.reporter || 'text')
this.cacheDirectory = config.cacheDir || findCacheDir({name: 'nyc', cwd: this.cwd})
this.enableCache = Boolean(this.cacheDirectory && (config.enableCache === true || process.env.NYC_CACHE === 'enable'))
this.exclude = testExclude({
cwd: this.cwd,
include: config.include,
exclude: config.exclude
})
// require extensions can be provided as config in package.json.
this.require = arrify(config.require)
this.extensions = arrify(config.extension).concat('.js').map(function (ext) {
return ext.toLowerCase()
}).filter(function (item, pos, arr) {
// avoid duplicate extensions
return arr.indexOf(item) === pos
})
this.transforms = this.extensions.reduce(function (transforms, ext) {
transforms[ext] = this._createTransform(ext)
return transforms
}.bind(this), {})
this.sourceMapCache = libSourceMaps.createSourceMapStore()
this.hookRunInContext = config.hookRunInContext
this.hashCache = {}
this.loadedMaps = null
this.fakeRequire = null
this.processInfo = new ProcessInfo(config && config._processInfo)
this.rootId = this.processInfo.root || this.generateUniqueID()
}
NYC.prototype._createTransform = function (ext) {
var _this = this
var opts = {
salt: JSON.stringify({
istanbul: require('istanbul-lib-coverage/package.json').version,
nyc: require('./package.json').version
}),
hash: function (code, metadata, salt) {
var hash = md5hex([code, metadata.filename, salt]) + '_' + CACHE_VERSION
_this.hashCache[metadata.filename] = hash
return hash
},
cacheDir: this.cacheDirectory,
disableCache: !this.enableCache,
ext: ext
}
if (this._eagerInstantiation) {
opts.transform = this._transformFactory(this.cacheDirectory)
} else {
opts.factory = this._transformFactory.bind(this)
}
return cachingTransform(opts)
}
NYC.prototype._loadAdditionalModules = function () {
var _this = this
this.require.forEach(function (r) {
// first attempt to require the module relative to
// the directory being instrumented.
var p = resolveFrom(_this.cwd, r)
if (p) {
require(p)
return
}
// now try other locations, .e.g, the nyc node_modules folder.
require(r)
})
}
NYC.prototype.instrumenter = function () {
return this._instrumenter || (this._instrumenter = this._createInstrumenter())
}
NYC.prototype._createInstrumenter = function () {
return this._instrumenterLib(this.cwd, {
produceSourceMap: this.config.produceSourceMap
})
}
NYC.prototype.addFile = function (filename) {
var relFile = path.relative(this.cwd, filename)
var source = this._readTranspiledSource(path.resolve(this.cwd, filename))
var instrumentedSource = this._maybeInstrumentSource(source, filename, relFile)
return {
instrument: !!instrumentedSource,
relFile: relFile,
content: instrumentedSource || source
}
}
NYC.prototype._readTranspiledSource = function (filePath) {
var source = null
var ext = path.extname(filePath)
if (typeof Module._extensions[ext] === 'undefined') {
ext = '.js'
}
Module._extensions[ext]({
_compile: function (content, filename) {
source = content
}
}, filePath)
return source
}
NYC.prototype.addAllFiles = function () {
var _this = this
this._loadAdditionalModules()
this.fakeRequire = true
this.walkAllFiles(this.cwd, function (filename) {
filename = path.resolve(_this.cwd, filename)
_this.addFile(filename)
var coverage = coverageFinder()
var lastCoverage = _this.instrumenter().lastFileCoverage()
if (lastCoverage) {
filename = lastCoverage.path
}
if (lastCoverage && _this.exclude.shouldInstrument(filename)) {
coverage[filename] = lastCoverage
}
})
this.fakeRequire = false
this.writeCoverageFile()
}
NYC.prototype.instrumentAllFiles = function (input, output, cb) {
var _this = this
var inputDir = '.' + path.sep
var visitor = function (filename) {
var ext
var transform
var inFile = path.resolve(inputDir, filename)
var code = fs.readFileSync(inFile, 'utf-8')
for (ext in _this.transforms) {
if (filename.toLowerCase().substr(-ext.length) === ext) {
transform = _this.transforms[ext]
break
}
}
if (transform) {
code = transform(code, {filename: filename, relFile: inFile})
}
if (!output) {
console.log(code)
} else {
var outFile = path.resolve(output, filename)
mkdirp.sync(path.dirname(outFile))
fs.writeFileSync(outFile, code, 'utf-8')
}
}
this._loadAdditionalModules()
try {
var stats = fs.lstatSync(input)
if (stats.isDirectory()) {
inputDir = input
this.walkAllFiles(input, visitor)
} else {
visitor(input)
}
} catch (err) {
return cb(err)
}
}
NYC.prototype.walkAllFiles = function (dir, visitor) {
var pattern = null
if (this.extensions.length === 1) {
pattern = '**/*' + this.extensions[0]
} else {
pattern = '**/*{' + this.extensions.join() + '}'
}
glob.sync(pattern, {cwd: dir, nodir: true, ignore: this.exclude.exclude}).forEach(function (filename) {
visitor(filename)
})
}
NYC.prototype._maybeInstrumentSource = function (code, filename, relFile) {
var instrument = this.exclude.shouldInstrument(filename, relFile)
if (!instrument) {
return null
}
var ext, transform
for (ext in this.transforms) {
if (filename.toLowerCase().substr(-ext.length) === ext) {
transform = this.transforms[ext]
break
}
}
return transform ? transform(code, {filename: filename, relFile: relFile}) : null
}
NYC.prototype._transformFactory = function (cacheDir) {
var _this = this
var instrumenter = this.instrumenter()
var instrumented
return function (code, metadata, hash) {
var filename = metadata.filename
var sourceMap = null
if (_this._sourceMap) sourceMap = _this._handleSourceMap(cacheDir, code, hash, filename)
try {
instrumented = instrumenter.instrumentSync(code, filename, sourceMap)
} catch (e) {
// don't fail external tests due to instrumentation bugs.
debugLog('failed to instrument ' + filename + 'with error: ' + e.stack)
instrumented = code
}
if (_this.fakeRequire) {
return 'function x () {}'
} else {
return instrumented
}
}
}
NYC.prototype._handleSourceMap = function (cacheDir, code, hash, filename) {
var sourceMap = convertSourceMap.fromSource(code) || convertSourceMap.fromMapFileSource(code, path.dirname(filename))
if (sourceMap) {
if (hash) {
var mapPath = path.join(cacheDir, hash + '.map')
fs.writeFileSync(mapPath, sourceMap.toJSON())
} else {
this.sourceMapCache.registerMap(filename, sourceMap.sourcemap)
}
}
return sourceMap
}
NYC.prototype._handleJs = function (code, filename) {
var relFile = path.relative(this.cwd, filename)
// ensure the path has correct casing (see istanbuljs/nyc#269 and nodejs/node#6624)
filename = path.resolve(this.cwd, relFile)
return this._maybeInstrumentSource(code, filename, relFile) || code
}
NYC.prototype._addHook = function (type) {
var handleJs = this._handleJs.bind(this)
var dummyMatcher = function () { return true } // we do all processing in transformer
libHook['hook' + type](dummyMatcher, handleJs, { extensions: this.extensions })
}
NYC.prototype._wrapRequire = function () {
this.extensions.forEach(function (ext) {
require.extensions[ext] = js
})
this._addHook('Require')
}
NYC.prototype._addOtherHooks = function () {
if (this.hookRunInContext) {
this._addHook('RunInThisContext')
}
}
NYC.prototype.cleanup = function () {
if (!process.env.NYC_CWD) rimraf.sync(this.tempDirectory())
}
NYC.prototype.clearCache = function () {
if (this.enableCache) {
rimraf.sync(this.cacheDirectory)
}
}
NYC.prototype.createTempDirectory = function () {
mkdirp.sync(this.tempDirectory())
if (this._showProcessTree) {
mkdirp.sync(this.processInfoDirectory())
}
}
NYC.prototype.reset = function () {
this.cleanup()
this.createTempDirectory()
}
NYC.prototype._wrapExit = function () {
var _this = this
// we always want to write coverage
// regardless of how the process exits.
onExit(function () {
_this.writeCoverageFile()
}, {alwaysLast: true})
}
NYC.prototype.wrap = function (bin) {
this._wrapRequire()
this._addOtherHooks()
this._wrapExit()
this._loadAdditionalModules()
return this
}
NYC.prototype.generateUniqueID = function () {
return md5hex(
process.hrtime().concat(process.pid).map(String)
)
}
NYC.prototype.writeCoverageFile = function () {
var coverage = coverageFinder()
if (!coverage) return
if (this.enableCache) {
Object.keys(coverage).forEach(function (absFile) {
if (this.hashCache[absFile] && coverage[absFile]) {
coverage[absFile].contentHash = this.hashCache[absFile]
}
}, this)
} else {
coverage = this.sourceMapTransform(coverage)
}
var id = this.generateUniqueID()
var coverageFilename = path.resolve(this.tempDirectory(), id + '.json')
fs.writeFileSync(
coverageFilename,
JSON.stringify(coverage),
'utf-8'
)
if (!this._showProcessTree) {
return
}
this.processInfo.coverageFilename = coverageFilename
fs.writeFileSync(
path.resolve(this.processInfoDirectory(), id + '.json'),
JSON.stringify(this.processInfo),
'utf-8'
)
}
NYC.prototype.sourceMapTransform = function (obj) {
var transformed = this.sourceMapCache.transformCoverage(
libCoverage.createCoverageMap(obj)
)
return transformed.map.data
}
function coverageFinder () {
var coverage = global.__coverage__
if (typeof __coverage__ === 'object') coverage = __coverage__
if (!coverage) coverage = global['__coverage__'] = {}
return coverage
}
NYC.prototype._getCoverageMapFromAllCoverageFiles = function () {
var map = libCoverage.createCoverageMap({})
this.loadReports().forEach(function (report) {
map.merge(report)
})
return map
}
NYC.prototype.report = function () {
var tree
var map = this._getCoverageMapFromAllCoverageFiles()
var context = libReport.createContext({
dir: this._reportDir,
watermarks: this.config.watermarks
})
tree = libReport.summarizers.pkg(map)
this.reporter.forEach(function (_reporter) {
tree.visit(reports.create(_reporter), context)
})
if (this._showProcessTree) {
this.showProcessTree()
}
}
NYC.prototype.showProcessTree = function () {
var processTree = ProcessInfo.buildProcessTree(this._loadProcessInfos())
console.log(processTree.render(this))
}
NYC.prototype.checkCoverage = function (thresholds) {
var map = this._getCoverageMapFromAllCoverageFiles()
var summary = map.getCoverageSummary()
// ERROR: Coverage for lines (90.12%) does not meet global threshold (120%)
Object.keys(thresholds).forEach(function (key) {
var coverage = summary[key].pct
if (coverage < thresholds[key]) {
process.exitCode = 1
console.error('ERROR: Coverage for ' + key + ' (' + coverage + '%) does not meet global threshold (' + thresholds[key] + '%)')
}
})
// process.exitCode was not implemented until v0.11.8.
if (/^v0\.(1[0-1]\.|[0-9]\.)/.test(process.version) && process.exitCode !== 0) process.exit(process.exitCode)
}
NYC.prototype._loadProcessInfos = function () {
var _this = this
var files = fs.readdirSync(this.processInfoDirectory())
return files.map(function (f) {
try {
return new ProcessInfo(JSON.parse(fs.readFileSync(
path.resolve(_this.processInfoDirectory(), f),
'utf-8'
)))
} catch (e) { // handle corrupt JSON output.
return {}
}
})
}
NYC.prototype.loadReports = function (filenames) {
var _this = this
var files = filenames || fs.readdirSync(this.tempDirectory())
var cacheDir = _this.cacheDirectory
var loadedMaps = this.loadedMaps || (this.loadedMaps = {})
return files.map(function (f) {
var report
try {
report = JSON.parse(fs.readFileSync(
path.resolve(_this.tempDirectory(), f),
'utf-8'
))
} catch (e) { // handle corrupt JSON output.
return {}
}
Object.keys(report).forEach(function (absFile) {
var fileReport = report[absFile]
if (fileReport && fileReport.contentHash) {
var hash = fileReport.contentHash
if (!(hash in loadedMaps)) {
try {
var mapPath = path.join(cacheDir, hash + '.map')
loadedMaps[hash] = JSON.parse(fs.readFileSync(mapPath, 'utf8'))
} catch (e) {
// set to false to avoid repeatedly trying to load the map
loadedMaps[hash] = false
}
}
if (loadedMaps[hash]) {
_this.sourceMapCache.registerMap(absFile, loadedMaps[hash])
}
}
})
report = _this.sourceMapTransform(report)
return report
})
}
NYC.prototype.tempDirectory = function () {
return path.resolve(this.cwd, this._tempDirectory)
}
NYC.prototype.processInfoDirectory = function () {
return path.resolve(this.tempDirectory(), 'processinfo')
}
module.exports = NYC
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| process.js | 14.55% | (8 / 55) | 0% | (0 / 12) | 0% | (0 / 12) | 14.55% | (8 / 55) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 1 1 1 1 1 1 1 1 | 'use strict'
var archy = require('archy')
var libCoverage = require('istanbul-lib-coverage')
function ProcessInfo (defaults) {
defaults = defaults || {}
this.pid = String(process.pid)
this.argv = process.argv
this.execArgv = process.execArgv
this.cwd = process.cwd()
this.time = Date.now()
this.ppid = null
this.root = null
this.coverageFilename = null
this.nodes = [] // list of children, filled by buildProcessTree()
this._coverageMap = null
for (var key in defaults) {
this[key] = defaults[key]
}
}
Object.defineProperty(ProcessInfo.prototype, 'label', {
get: function () {
if (this._label) {
return this._label
}
var covInfo = ''
if (this._coverageMap) {
covInfo = '\n ' + this._coverageMap.getCoverageSummary().lines.pct + ' % Lines'
}
return this.argv.join(' ') + covInfo
}
})
ProcessInfo.buildProcessTree = function (infos) {
var treeRoot = new ProcessInfo({ _label: 'nyc' })
var nodes = { }
infos = infos.sort(function (a, b) {
return a.time - b.time
})
infos.forEach(function (p) {
nodes[p.root + ':' + p.pid] = p
})
infos.forEach(function (p) {
if (!p.ppid) {
return
}
var parent = nodes[p.root + ':' + p.ppid]
if (!parent) {
parent = treeRoot
}
parent.nodes.push(p)
})
return treeRoot
}
ProcessInfo.prototype.getCoverageMap = function (merger) {
if (this._coverageMap) {
return this._coverageMap
}
var childMaps = this.nodes.map(function (child) {
return child.getCoverageMap(merger)
})
this._coverageMap = merger([this.coverageFilename], childMaps)
return this._coverageMap
}
ProcessInfo.prototype.render = function (nyc) {
this.getCoverageMap(function (filenames, maps) {
var map = libCoverage.createCoverageMap({})
nyc.loadReports(filenames).forEach(function (report) {
map.merge(report)
})
maps.forEach(function (otherMap) {
map.merge(otherMap)
})
return map
})
return archy(this)
}
module.exports = ProcessInfo
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 13.95% | (6 / 43) | 0% | (0 / 20) | 0% | (0 / 9) | 13.95% | (6 / 43) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | 1 1 1 1 1 1 | 'use strict';
var js = require('default-require-extensions/js');
module.exports = appendTransform;
var count = 0;
function appendTransform(transform, ext, extensions) {
// Generate a unique key for this transform
var key = __dirname + count; // eslint-disable-line
count++;
ext = ext || '.js';
extensions = extensions || require.extensions;
var forwardGet;
var forwardSet;
var descriptor = Object.getOwnPropertyDescriptor(extensions, ext) || {value: js, configurable: true};
if (
((descriptor.get || descriptor.set) && !(descriptor.get && descriptor.set)) ||
!descriptor.configurable
) {
throw new Error('Somebody did bad things to require.extensions["' + ext + '"]');
}
if (descriptor.get) {
// wrap a previous append-transform install and pass through to the getter/setter pair it created
forwardGet = function () {
return descriptor.get();
};
forwardSet = function (val) {
descriptor.set(val);
return forwardGet();
};
} else {
forwardGet = function () {
return descriptor.value;
};
forwardSet = function (val) {
descriptor.value = val;
return val;
};
}
function wrapCustomHook(hook) {
return function (module, filename) {
// We wrap every added extension, but we only apply the transform to the one on top of the stack
if (!module[key]) {
module[key] = true;
var originalCompile = module._compile;
module._compile = function replacementCompile(code, filename) {
module._compile = originalCompile;
code = transform(code, filename);
module._compile(code, filename);
};
}
hook(module, filename);
};
}
// wrap the original
forwardSet(wrapCustomHook(forwardGet()));
var hooks = [forwardGet()];
function setCurrentHook(hook) {
var restoreIndex = hooks.indexOf(hook);
if (restoreIndex === -1) {
hooks.push(forwardSet(wrapCustomHook(hook)));
} else {
// we have already scene this hook, and it is being reverted (proxyquire, etc) - don't wrap again.
hooks.splice(restoreIndex + 1, hooks.length);
forwardSet(hook);
}
}
Object.defineProperty(extensions, ext, {
configurable: true,
enumerable: true,
get: forwardGet,
set: setCurrentHook
});
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 5.56% | (1 / 18) | 0% | (0 / 22) | 0% | (0 / 3) | 6.67% | (1 / 15) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 1 | module.exports = function archy (obj, prefix, opts) { if (prefix === undefined) prefix = ''; if (!opts) opts = {}; var chr = function (s) { var chars = { '│' : '|', '└' : '`', '├' : '+', '─' : '-', '┬' : '-' }; return opts.unicode === false ? chars[s] : s; }; if (typeof obj === 'string') obj = { label : obj }; var nodes = obj.nodes || []; var lines = (obj.label || '').split('\n'); var splitter = '\n' + prefix + (nodes.length ? chr('│') : ' ') + ' '; return prefix + lines.join(splitter) + '\n' + nodes.map(function (node, ix) { var last = ix === nodes.length - 1; var more = node.nodes && node.nodes.length; var prefix_ = prefix + (last ? ' ' : chr('│')) + ' '; return prefix + (last ? chr('└') : chr('├')) + chr('─') + (more ? chr('┬') : chr('─')) + ' ' + archy(node, prefix_, opts).slice(prefix.length + 2) ; }).join('') ; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 26.67% | (4 / 15) | 0% | (0 / 6) | 0% | (0 / 1) | 26.67% | (4 / 15) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 1 1 1 1 | /*!
* arr-diff <https://github.com/jonschlinkert/arr-diff>
*
* Copyright (c) 2014 Jon Schlinkert, contributors.
* Licensed under the MIT License
*/
'use strict';
var flatten = require('arr-flatten');
var slice = [].slice;
/**
* Return the difference between the first array and
* additional arrays.
*
* ```js
* var diff = require('{%= name %}');
*
* var a = ['a', 'b', 'c', 'd'];
* var b = ['b', 'c'];
*
* console.log(diff(a, b))
* //=> ['a', 'd']
* ```
*
* @param {Array} `a`
* @param {Array} `b`
* @return {Array}
* @api public
*/
function diff(arr, arrays) {
var argsLen = arguments.length;
var len = arr.length, i = -1;
var res = [], arrays;
if (argsLen === 1) {
return arr;
}
if (argsLen > 2) {
arrays = flatten(slice.call(arguments, 1));
}
while (++i < len) {
if (!~arrays.indexOf(arr[i])) {
res.push(arr[i]);
}
}
return res;
}
/**
* Expose `diff`
*/
module.exports = diff;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 18.18% | (2 / 11) | 0% | (0 / 2) | 0% | (0 / 2) | 18.18% | (2 / 11) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 1 1 | /*! * arr-flatten <https://github.com/jonschlinkert/arr-flatten> * * Copyright (c) 2014-2015, Jon Schlinkert. * Licensed under the MIT License. */ 'use strict'; module.exports = function flatten(arr) { return flat(arr, []); }; function flat(arr, res) { var len = arr.length; var i = -1; while (len--) { var cur = arr[++i]; if (Array.isArray(cur)) { flat(cur, res); } else { res.push(cur); } } return res; } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 9.09% | (1 / 11) | 0% | (0 / 4) | 0% | (0 / 1) | 9.09% | (1 / 11) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 1 | /*! * array-unique <https://github.com/jonschlinkert/array-unique> * * Copyright (c) 2014-2015, Jon Schlinkert. * Licensed under the MIT License. */ 'use strict'; module.exports = function unique(arr) { if (!Array.isArray(arr)) { throw new TypeError('array-unique expects an array.'); } var len = arr.length; var i = -1; while (i++ < len) { var j = i + 1; for (; j < arr.length; ++j) { if (arr[i] === arr[j]) { arr.splice(j--, 1); } } } return arr; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 25% | (1 / 4) | 0% | (0 / 6) | 0% | (0 / 1) | 25% | (1 / 4) |
| 1 2 3 4 5 6 7 8 9 10 | 1 | 'use strict'; module.exports = function (val) { if (val === null || val === undefined) { return []; } return Array.isArray(val) ? val : [val]; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 14.29% | (5 / 35) | 0% | (0 / 26) | 0% | (0 / 3) | 15.15% | (5 / 33) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 1 1 1 1 1 | module.exports = balanced; function balanced(a, b, str) { if (a instanceof RegExp) a = maybeMatch(a, str); if (b instanceof RegExp) b = maybeMatch(b, str); var r = range(a, b, str); return r && { start: r[0], end: r[1], pre: str.slice(0, r[0]), body: str.slice(r[0] + a.length, r[1]), post: str.slice(r[1] + b.length) }; } function maybeMatch(reg, str) { var m = str.match(reg); return m ? m[0] : null; } balanced.range = range; function range(a, b, str) { var begs, beg, left, right, result; var ai = str.indexOf(a); var bi = str.indexOf(b, ai + 1); var i = ai; if (ai >= 0 && bi > 0) { begs = []; left = str.length; while (i >= 0 && !result) { if (i == ai) { begs.push(i); ai = str.indexOf(a, i + 1); } else if (begs.length == 1) { result = [ begs.pop(), bi ]; } else { beg = begs.pop(); if (beg < left) { left = beg; right = bi; } bi = str.indexOf(b, i + 1); } i = ai < bi && ai >= 0 ? ai : bi; } if (begs.length) { result = [ left, right ]; } } return result; } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 17.27% | (19 / 110) | 0% | (0 / 55) | 0% | (0 / 13) | 17.59% | (19 / 108) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var concatMap = require('concat-map');
var balanced = require('balanced-match');
module.exports = expandTop;
var escSlash = '\0SLASH'+Math.random()+'\0';
var escOpen = '\0OPEN'+Math.random()+'\0';
var escClose = '\0CLOSE'+Math.random()+'\0';
var escComma = '\0COMMA'+Math.random()+'\0';
var escPeriod = '\0PERIOD'+Math.random()+'\0';
function numeric(str) {
return parseInt(str, 10) == str
? parseInt(str, 10)
: str.charCodeAt(0);
}
function escapeBraces(str) {
return str.split('\\\\').join(escSlash)
.split('\\{').join(escOpen)
.split('\\}').join(escClose)
.split('\\,').join(escComma)
.split('\\.').join(escPeriod);
}
function unescapeBraces(str) {
return str.split(escSlash).join('\\')
.split(escOpen).join('{')
.split(escClose).join('}')
.split(escComma).join(',')
.split(escPeriod).join('.');
}
// Basically just str.split(","), but handling cases
// where we have nested braced sections, which should be
// treated as individual members, like {a,{b,c},d}
function parseCommaParts(str) {
if (!str)
return [''];
var parts = [];
var m = balanced('{', '}', str);
if (!m)
return str.split(',');
var pre = m.pre;
var body = m.body;
var post = m.post;
var p = pre.split(',');
p[p.length-1] += '{' + body + '}';
var postParts = parseCommaParts(post);
if (post.length) {
p[p.length-1] += postParts.shift();
p.push.apply(p, postParts);
}
parts.push.apply(parts, p);
return parts;
}
function expandTop(str) {
if (!str)
return [];
// I don't know why Bash 4.3 does this, but it does.
// Anything starting with {} will have the first two bytes preserved
// but *only* at the top level, so {},a}b will not expand to anything,
// but a{},b}c will be expanded to [a}c,abc].
// One could argue that this is a bug in Bash, but since the goal of
// this module is to match Bash's rules, we escape a leading {}
if (str.substr(0, 2) === '{}') {
str = '\\{\\}' + str.substr(2);
}
return expand(escapeBraces(str), true).map(unescapeBraces);
}
function identity(e) {
return e;
}
function embrace(str) {
return '{' + str + '}';
}
function isPadded(el) {
return /^-?0\d/.test(el);
}
function lte(i, y) {
return i <= y;
}
function gte(i, y) {
return i >= y;
}
function expand(str, isTop) {
var expansions = [];
var m = balanced('{', '}', str);
if (!m || /\$$/.test(m.pre)) return [str];
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
var isSequence = isNumericSequence || isAlphaSequence;
var isOptions = /^(.*,)+(.+)?$/.test(m.body);
if (!isSequence && !isOptions) {
// {a},b}
if (m.post.match(/,.*\}/)) {
str = m.pre + '{' + m.body + escClose + m.post;
return expand(str);
}
return [str];
}
var n;
if (isSequence) {
n = m.body.split(/\.\./);
} else {
n = parseCommaParts(m.body);
if (n.length === 1) {
// x{{a,b}}y ==> x{a}y x{b}y
n = expand(n[0], false).map(embrace);
if (n.length === 1) {
var post = m.post.length
? expand(m.post, false)
: [''];
return post.map(function(p) {
return m.pre + n[0] + p;
});
}
}
}
// at this point, n is the parts, and we know it's not a comma set
// with a single entry.
// no need to expand pre, since it is guaranteed to be free of brace-sets
var pre = m.pre;
var post = m.post.length
? expand(m.post, false)
: [''];
var N;
if (isSequence) {
var x = numeric(n[0]);
var y = numeric(n[1]);
var width = Math.max(n[0].length, n[1].length)
var incr = n.length == 3
? Math.abs(numeric(n[2]))
: 1;
var test = lte;
var reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
}
var pad = n.some(isPadded);
N = [];
for (var i = x; test(i, y); i += incr) {
var c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === '\\')
c = '';
} else {
c = String(i);
if (pad) {
var need = width - c.length;
if (need > 0) {
var z = new Array(need + 1).join('0');
if (i < 0)
c = '-' + z + c.slice(1);
else
c = z + c;
}
}
}
N.push(c);
}
} else {
N = concatMap(n, function(el) { return expand(el, false) });
}
for (var j = 0; j < N.length; j++) {
for (var k = 0; k < post.length; k++) {
var expansion = pre + N[j] + post[k];
if (!isTop || isSequence || expansion)
expansions.push(expansion);
}
}
return expansions;
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 12.15% | (22 / 181) | 0% | (0 / 101) | 0% | (0 / 21) | 12.43% | (22 / 177) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*!
* braces <https://github.com/jonschlinkert/braces>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
/**
* Module dependencies
*/
var expand = require('expand-range');
var repeat = require('repeat-element');
var tokens = require('preserve');
/**
* Expose `braces`
*/
module.exports = function(str, options) {
if (typeof str !== 'string') {
throw new Error('braces expects a string');
}
return braces(str, options);
};
/**
* Expand `{foo,bar}` or `{1..5}` braces in the
* given `string`.
*
* @param {String} `str`
* @param {Array} `arr`
* @param {Object} `options`
* @return {Array}
*/
function braces(str, arr, options) {
if (str === '') {
return [];
}
if (!Array.isArray(arr)) {
options = arr;
arr = [];
}
var opts = options || {};
arr = arr || [];
if (typeof opts.nodupes === 'undefined') {
opts.nodupes = true;
}
var fn = opts.fn;
var es6;
if (typeof opts === 'function') {
fn = opts;
opts = {};
}
if (!(patternRe instanceof RegExp)) {
patternRe = patternRegex();
}
var matches = str.match(patternRe) || [];
var m = matches[0];
switch(m) {
case '\\,':
return escapeCommas(str, arr, opts);
case '\\.':
return escapeDots(str, arr, opts);
case '\/.':
return escapePaths(str, arr, opts);
case ' ':
return splitWhitespace(str);
case '{,}':
return exponential(str, opts, braces);
case '{}':
return emptyBraces(str, arr, opts);
case '\\{':
case '\\}':
return escapeBraces(str, arr, opts);
case '${':
if (!/\{[^{]+\{/.test(str)) {
return arr.concat(str);
} else {
es6 = true;
str = tokens.before(str, es6Regex());
}
}
if (!(braceRe instanceof RegExp)) {
braceRe = braceRegex();
}
var match = braceRe.exec(str);
if (match == null) {
return [str];
}
var outter = match[1];
var inner = match[2];
if (inner === '') { return [str]; }
var segs, segsLength;
if (inner.indexOf('..') !== -1) {
segs = expand(inner, opts, fn) || inner.split(',');
segsLength = segs.length;
} else if (inner[0] === '"' || inner[0] === '\'') {
return arr.concat(str.split(/['"]/).join(''));
} else {
segs = inner.split(',');
if (opts.makeRe) {
return braces(str.replace(outter, wrap(segs, '|')), opts);
}
segsLength = segs.length;
if (segsLength === 1 && opts.bash) {
segs[0] = wrap(segs[0], '\\');
}
}
var len = segs.length;
var i = 0, val;
while (len--) {
var path = segs[i++];
if (/(\.[^.\/])/.test(path)) {
if (segsLength > 1) {
return segs;
} else {
return [str];
}
}
val = splice(str, outter, path);
if (/\{[^{}]+?\}/.test(val)) {
arr = braces(val, arr, opts);
} else if (val !== '') {
if (opts.nodupes && arr.indexOf(val) !== -1) { continue; }
arr.push(es6 ? tokens.after(val) : val);
}
}
if (opts.strict) { return filter(arr, filterEmpty); }
return arr;
}
/**
* Expand exponential ranges
*
* `a{,}{,}` => ['a', 'a', 'a', 'a']
*/
function exponential(str, options, fn) {
if (typeof options === 'function') {
fn = options;
options = null;
}
var opts = options || {};
var esc = '__ESC_EXP__';
var exp = 0;
var res;
var parts = str.split('{,}');
if (opts.nodupes) {
return fn(parts.join(''), opts);
}
exp = parts.length - 1;
res = fn(parts.join(esc), opts);
var len = res.length;
var arr = [];
var i = 0;
while (len--) {
var ele = res[i++];
var idx = ele.indexOf(esc);
if (idx === -1) {
arr.push(ele);
} else {
ele = ele.split('__ESC_EXP__').join('');
if (!!ele && opts.nodupes !== false) {
arr.push(ele);
} else {
var num = Math.pow(2, exp);
arr.push.apply(arr, repeat(ele, num));
}
}
}
return arr;
}
/**
* Wrap a value with parens, brackets or braces,
* based on the given character/separator.
*
* @param {String|Array} `val`
* @param {String} `ch`
* @return {String}
*/
function wrap(val, ch) {
if (ch === '|') {
return '(' + val.join(ch) + ')';
}
if (ch === ',') {
return '{' + val.join(ch) + '}';
}
if (ch === '-') {
return '[' + val.join(ch) + ']';
}
if (ch === '\\') {
return '\\{' + val + '\\}';
}
}
/**
* Handle empty braces: `{}`
*/
function emptyBraces(str, arr, opts) {
return braces(str.split('{}').join('\\{\\}'), arr, opts);
}
/**
* Filter out empty-ish values
*/
function filterEmpty(ele) {
return !!ele && ele !== '\\';
}
/**
* Handle patterns with whitespace
*/
function splitWhitespace(str) {
var segs = str.split(' ');
var len = segs.length;
var res = [];
var i = 0;
while (len--) {
res.push.apply(res, braces(segs[i++]));
}
return res;
}
/**
* Handle escaped braces: `\\{foo,bar}`
*/
function escapeBraces(str, arr, opts) {
if (!/\{[^{]+\{/.test(str)) {
return arr.concat(str.split('\\').join(''));
} else {
str = str.split('\\{').join('__LT_BRACE__');
str = str.split('\\}').join('__RT_BRACE__');
return map(braces(str, arr, opts), function(ele) {
ele = ele.split('__LT_BRACE__').join('{');
return ele.split('__RT_BRACE__').join('}');
});
}
}
/**
* Handle escaped dots: `{1\\.2}`
*/
function escapeDots(str, arr, opts) {
if (!/[^\\]\..+\\\./.test(str)) {
return arr.concat(str.split('\\').join(''));
} else {
str = str.split('\\.').join('__ESC_DOT__');
return map(braces(str, arr, opts), function(ele) {
return ele.split('__ESC_DOT__').join('.');
});
}
}
/**
* Handle escaped dots: `{1\\.2}`
*/
function escapePaths(str, arr, opts) {
str = str.split('\/.').join('__ESC_PATH__');
return map(braces(str, arr, opts), function(ele) {
return ele.split('__ESC_PATH__').join('\/.');
});
}
/**
* Handle escaped commas: `{a\\,b}`
*/
function escapeCommas(str, arr, opts) {
if (!/\w,/.test(str)) {
return arr.concat(str.split('\\').join(''));
} else {
str = str.split('\\,').join('__ESC_COMMA__');
return map(braces(str, arr, opts), function(ele) {
return ele.split('__ESC_COMMA__').join(',');
});
}
}
/**
* Regex for common patterns
*/
function patternRegex() {
return /\${|( (?=[{,}])|(?=[{,}]) )|{}|{,}|\\,(?=.*[{}])|\/\.(?=.*[{}])|\\\.(?={)|\\{|\\}/;
}
/**
* Braces regex.
*/
function braceRegex() {
return /.*(\\?\{([^}]+)\})/;
}
/**
* es6 delimiter regex.
*/
function es6Regex() {
return /\$\{([^}]+)\}/;
}
var braceRe;
var patternRe;
/**
* Faster alternative to `String.replace()` when the
* index of the token to be replaces can't be supplied
*/
function splice(str, token, replacement) {
var i = str.indexOf(token);
return str.substr(0, i) + replacement
+ str.substr(i + token.length);
}
/**
* Fast array map
*/
function map(arr, fn) {
if (arr == null) {
return [];
}
var len = arr.length;
var res = new Array(len);
var i = -1;
while (++i < len) {
res[i] = fn(arr[i], i, arr);
}
return res;
}
/**
* Fast array filter
*/
function filter(arr, cb) {
if (arr == null) return [];
if (typeof cb !== 'function') {
throw new TypeError('braces: filter expects a callback function.');
}
var len = arr.length;
var res = arr.slice();
var i = 0;
while (len--) {
if (!cb(arr[len], i++)) {
res.splice(len, 1);
}
}
return res;
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 100% | (3 / 3) | 100% | (2 / 2) | 100% | (1 / 1) | 100% | (3 / 3) |
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 1 83 | 'use strict';
var blacklist = [
'freelist',
'sys'
];
module.exports = Object.keys(process.binding('natives')).filter(function (el) {
return !/^_|^internal|\//.test(el) && blacklist.indexOf(el) === -1;
}).sort();
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 20.45% | (9 / 44) | 0% | (0 / 39) | 0% | (0 / 4) | 20.45% | (9 / 44) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 1 1 1 1 1 1 1 1 1 | 'use strict';
var mkdirp = require('mkdirp');
var md5Hex = require('md5-hex');
var fs = require('fs');
var path = require('path');
var writeFileAtomic = require('write-file-atomic');
function defaultHash(input, additionalData, salt) {
return md5Hex([input, salt || '']);
}
function wrap(opts) {
if (!(opts.factory || opts.transform) || (opts.factory && opts.transform)) {
throw new Error('specify factory or transform but not both');
}
if (typeof opts.cacheDir !== 'string' && !opts.disableCache) {
throw new Error('cacheDir must be a string');
}
var transformFn = opts.transform;
var factory = opts.factory;
var cacheDir = opts.cacheDir;
var cacheDirCreated = opts.createCacheDir === false;
var created = transformFn && cacheDirCreated;
var ext = opts.ext || '';
var salt = opts.salt || '';
var shouldTransform = opts.shouldTransform;
var disableCache = opts.disableCache;
var hashFn = opts.hash || defaultHash;
var encoding = opts.encoding === 'buffer' ? undefined : opts.encoding || 'utf8';
function transform(input, metadata, hash) {
if (!created) {
if (!cacheDirCreated && !disableCache) {
mkdirp.sync(cacheDir);
}
if (!transformFn) {
transformFn = factory(cacheDir);
}
created = true;
}
return transformFn(input, metadata, hash);
}
return function (input, metadata) {
if (shouldTransform && !shouldTransform(input, metadata)) {
return input;
}
if (disableCache) {
return transform(input, metadata);
}
var hash = hashFn(input, metadata, salt);
var cachedPath = path.join(cacheDir, hash + ext);
try {
return fs.readFileSync(cachedPath, encoding);
} catch (e) {
var result = transform(input, metadata, hash);
writeFileAtomic.sync(cachedPath, result, encoding);
return result;
}
};
}
module.exports = wrap;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 15.38% | (2 / 13) | 0% | (0 / 8) | 0% | (0 / 3) | 15.38% | (2 / 13) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 1 1 | var path = require('path');
module.exports = function (basedir, relfiles) {
if (relfiles) {
var files = relfiles.map(function (r) {
return path.resolve(basedir, r);
});
}
else {
var files = basedir;
}
var res = files.slice(1).reduce(function (ps, file) {
if (!file.match(/^([A-Za-z]:)?\/|\\/)) {
throw new Error('relative path without a basedir');
}
var xs = file.split(/\/+|\\+/);
for (
var i = 0;
ps[i] === xs[i] && i < Math.min(ps.length, xs.length);
i++
);
return ps.slice(0, i);
}, files[0].split(/\/+|\\+/));
// Windows correctly handles paths with forward-slashes
return res.length > 1 ? res.join('/') : '/'
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 20% | (2 / 10) | 25% | (1 / 4) | 0% | (0 / 2) | 22.22% | (2 / 9) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 1 | module.exports = function (xs, fn) { var res = []; for (var i = 0; i < xs.length; i++) { var x = fn(xs[i], i); if (isArray(x)) res.push.apply(res, x); else res.push(x); } return res; }; var isArray = Array.isArray || function (xs) { return Object.prototype.toString.call(xs) === '[object Array]'; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 36% | (27 / 75) | 0% | (0 / 28) | 0% | (0 / 23) | 38.57% | (27 / 70) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var fs = require('fs');
var path = require('path');
var commentRx = /^\s*\/(?:\/|\*)[@#]\s+sourceMappingURL=data:(?:application|text)\/json;(?:charset[:=]\S+?;)?base64,(?:.*)$/mg;
var mapFileCommentRx =
//Example (Extra space between slashes added to solve Safari bug. Exclude space in production):
// / /# sourceMappingURL=foo.js.map /*# sourceMappingURL=foo.js.map */
/(?:\/\/[@#][ \t]+sourceMappingURL=([^\s'"]+?)[ \t]*$)|(?:\/\*[@#][ \t]+sourceMappingURL=([^\*]+?)[ \t]*(?:\*\/){1}[ \t]*$)/mg
function decodeBase64(base64) {
return new Buffer(base64, 'base64').toString();
}
function stripComment(sm) {
return sm.split(',').pop();
}
function readFromFileMap(sm, dir) {
// NOTE: this will only work on the server since it attempts to read the map file
mapFileCommentRx.lastIndex = 0;
var r = mapFileCommentRx.exec(sm);
// for some odd reason //# .. captures in 1 and /* .. */ in 2
var filename = r[1] || r[2];
var filepath = path.resolve(dir, filename);
try {
return fs.readFileSync(filepath, 'utf8');
} catch (e) {
throw new Error('An error occurred while trying to read the map file at ' + filepath + '\n' + e);
}
}
function Converter (sm, opts) {
opts = opts || {};
if (opts.isFileComment) sm = readFromFileMap(sm, opts.commentFileDir);
if (opts.hasComment) sm = stripComment(sm);
if (opts.isEncoded) sm = decodeBase64(sm);
if (opts.isJSON || opts.isEncoded) sm = JSON.parse(sm);
this.sourcemap = sm;
}
Converter.prototype.toJSON = function (space) {
return JSON.stringify(this.sourcemap, null, space);
};
Converter.prototype.toBase64 = function () {
var json = this.toJSON();
return new Buffer(json).toString('base64');
};
Converter.prototype.toComment = function (options) {
var base64 = this.toBase64();
var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64;
return options && options.multiline ? '/*# ' + data + ' */' : '//# ' + data;
};
// returns copy instead of original
Converter.prototype.toObject = function () {
return JSON.parse(this.toJSON());
};
Converter.prototype.addProperty = function (key, value) {
if (this.sourcemap.hasOwnProperty(key)) throw new Error('property %s already exists on the sourcemap, use set property instead');
return this.setProperty(key, value);
};
Converter.prototype.setProperty = function (key, value) {
this.sourcemap[key] = value;
return this;
};
Converter.prototype.getProperty = function (key) {
return this.sourcemap[key];
};
exports.fromObject = function (obj) {
return new Converter(obj);
};
exports.fromJSON = function (json) {
return new Converter(json, { isJSON: true });
};
exports.fromBase64 = function (base64) {
return new Converter(base64, { isEncoded: true });
};
exports.fromComment = function (comment) {
comment = comment
.replace(/^\/\*/g, '//')
.replace(/\*\/$/g, '');
return new Converter(comment, { isEncoded: true, hasComment: true });
};
exports.fromMapFileComment = function (comment, dir) {
return new Converter(comment, { commentFileDir: dir, isFileComment: true, isJSON: true });
};
// Finds last sourcemap comment in file or returns null if none was found
exports.fromSource = function (content) {
var m = content.match(commentRx);
return m ? exports.fromComment(m.pop()) : null;
};
// Finds last sourcemap comment in file or returns null if none was found
exports.fromMapFileSource = function (content, dir) {
var m = content.match(mapFileCommentRx);
return m ? exports.fromMapFileComment(m.pop(), dir) : null;
};
exports.removeComments = function (src) {
return src.replace(commentRx, '');
};
exports.removeMapFileComments = function (src) {
return src.replace(mapFileCommentRx, '');
};
exports.generateMapFileComment = function (file, options) {
var data = 'sourceMappingURL=' + file;
return options && options.multiline ? '/*# ' + data + ' */' : '//# ' + data;
};
Object.defineProperty(exports, 'commentRegex', {
get: function getCommentRegex () {
return commentRx;
}
});
Object.defineProperty(exports, 'mapFileCommentRegex', {
get: function getMapFileCommentRegex () {
return mapFileCommentRx;
}
});
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 75% | (9 / 12) | 66.67% | (4 / 6) | 33.33% | (1 / 3) | 75% | (9 / 12) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 1 1 1 1 1 1 1 1 1 | 'use strict';
// https://github.com/joyent/node/blob/fbfe562d71ae8d8f8bbf627808c755e513e4e905/lib/util.js#L96-L114
var util = require('util');
var debugEnv = process.env.NODE_DEBUG || '';
var cache = {};
module.exports = function (set) {
set = set.toUpperCase();
Eif (!cache[set]) {
Iif (new RegExp('\\b' + set + '\\b', 'i').test(debugEnv)) {
var pid = process.pid;
cache[set] = function () {
console.error('%s %d: %s', set, pid, util.format.apply(util, arguments));
};
} else {
cache[set] = function () {};
}
}
return cache[set];
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| js.js | 60% | (3 / 5) | 100% | (0 / 0) | 0% | (0 / 1) | 60% | (3 / 5) |
| 1 2 3 4 5 6 7 8 9 10 11 | 1 1 1 | 'use strict';
var fs = require('fs');
var stripBom = require('strip-bom');
module.exports = function (module, filename) {
var content = fs.readFileSync(filename, 'utf8');
module._compile(stripBom(content), filename);
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 20.31% | (13 / 64) | 10% | (4 / 40) | 22.22% | (2 / 9) | 20.31% | (13 / 64) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var util = require('util');
var isArrayish = require('is-arrayish');
var errorEx = function errorEx(name, properties) {
Iif (!name || name.constructor !== String) {
properties = name || {};
name = Error.name;
}
var errorExError = function ErrorEXError(message) {
if (!this) {
return new ErrorEXError(message);
}
message = message instanceof Error
? message.message
: (message || this.message);
Error.call(this, message);
Error.captureStackTrace(this, errorExError);
this.name = name;
Object.defineProperty(this, 'message', {
configurable: true,
enumerable: false,
get: function () {
var newMessage = message.split(/\r?\n/g);
for (var key in properties) {
if (!properties.hasOwnProperty(key)) {
continue;
}
var modifier = properties[key];
if ('message' in modifier) {
newMessage = modifier.message(this[key], newMessage) || newMessage;
if (!isArrayish(newMessage)) {
newMessage = [newMessage];
}
}
}
return newMessage.join('\n');
},
set: function (v) {
message = v;
}
});
var stackDescriptor = Object.getOwnPropertyDescriptor(this, 'stack');
var stackGetter = stackDescriptor.get;
var stackValue = stackDescriptor.value;
delete stackDescriptor.value;
delete stackDescriptor.writable;
stackDescriptor.get = function () {
var stack = (stackGetter)
? stackGetter.call(this).split(/\r?\n+/g)
: stackValue.split(/\r?\n+/g);
// starting in Node 7, the stack builder caches the message.
// just replace it.
stack[0] = this.name + ': ' + this.message;
var lineCount = 1;
for (var key in properties) {
if (!properties.hasOwnProperty(key)) {
continue;
}
var modifier = properties[key];
if ('line' in modifier) {
var line = modifier.line(this[key]);
if (line) {
stack.splice(lineCount++, 0, ' ' + line);
}
}
if ('stack' in modifier) {
modifier.stack(this[key], stack);
}
}
return stack.join('\n');
};
Object.defineProperty(this, 'stack', stackDescriptor);
};
Eif (Object.setPrototypeOf) {
Object.setPrototypeOf(errorExError.prototype, Error.prototype);
Object.setPrototypeOf(errorExError, Error);
} else {
util.inherits(errorExError, Error);
}
return errorExError;
};
errorEx.append = function (str, def) {
return {
message: function (v, message) {
v = v || def;
if (v) {
message[0] += ' ' + str.replace('%s', v.toString());
}
return message;
}
};
};
errorEx.line = function (str, def) {
return {
line: function (v) {
v = v || def;
if (v) {
return str.replace('%s', v.toString());
}
return null;
}
};
};
module.exports = errorEx;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 8.43% | (7 / 83) | 0% | (0 / 50) | 0% | (0 / 4) | 8.43% | (7 / 83) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 1 1 1 1 1 1 1 | /*!
* expand-brackets <https://github.com/jonschlinkert/expand-brackets>
*
* Copyright (c) 2015 Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
var isPosixBracket = require('is-posix-bracket');
/**
* POSIX character classes
*/
var POSIX = {
alnum: 'a-zA-Z0-9',
alpha: 'a-zA-Z',
blank: ' \\t',
cntrl: '\\x00-\\x1F\\x7F',
digit: '0-9',
graph: '\\x21-\\x7E',
lower: 'a-z',
print: '\\x20-\\x7E',
punct: '-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',
space: ' \\t\\r\\n\\v\\f',
upper: 'A-Z',
word: 'A-Za-z0-9_',
xdigit: 'A-Fa-f0-9',
};
/**
* Expose `brackets`
*/
module.exports = brackets;
function brackets(str) {
if (!isPosixBracket(str)) {
return str;
}
var negated = false;
if (str.indexOf('[^') !== -1) {
negated = true;
str = str.split('[^').join('[');
}
if (str.indexOf('[!') !== -1) {
negated = true;
str = str.split('[!').join('[');
}
var a = str.split('[');
var b = str.split(']');
var imbalanced = a.length !== b.length;
var parts = str.split(/(?::\]\[:|\[?\[:|:\]\]?)/);
var len = parts.length, i = 0;
var end = '', beg = '';
var res = [];
// start at the end (innermost) first
while (len--) {
var inner = parts[i++];
if (inner === '^[!' || inner === '[!') {
inner = '';
negated = true;
}
var prefix = negated ? '^' : '';
var ch = POSIX[inner];
if (ch) {
res.push('[' + prefix + ch + ']');
} else if (inner) {
if (/^\[?\w-\w\]?$/.test(inner)) {
if (i === parts.length) {
res.push('[' + prefix + inner);
} else if (i === 1) {
res.push(prefix + inner + ']');
} else {
res.push(prefix + inner);
}
} else {
if (i === 1) {
beg += inner;
} else if (i === parts.length) {
end += inner;
} else {
res.push('[' + prefix + inner + ']');
}
}
}
}
var result = res.join('|');
var rlen = res.length || 1;
if (rlen > 1) {
result = '(?:' + result + ')';
rlen = 1;
}
if (beg) {
rlen++;
if (beg.charAt(0) === '[') {
if (imbalanced) {
beg = '\\[' + beg.slice(1);
} else {
beg += ']';
}
}
result = beg + result;
}
if (end) {
rlen++;
if (end.slice(-1) === ']') {
if (imbalanced) {
end = end.slice(0, end.length - 1) + '\\]';
} else {
end = '[' + end;
}
}
result += end;
}
if (rlen > 1) {
result = result.split('][').join(']|[');
if (result.indexOf('|') !== -1 && !/\(\?/.test(result)) {
result = '(?:' + result + ')';
}
}
result = result.replace(/\[+=|=\]+/g, '\\b');
return result;
}
brackets.makeRe = function(pattern) {
try {
return new RegExp(brackets(pattern));
} catch (err) {}
};
brackets.isMatch = function(str, pattern) {
try {
return brackets.makeRe(pattern).test(str);
} catch (err) {
return false;
}
};
brackets.match = function(arr, pattern) {
var len = arr.length, i = 0;
var res = arr.slice();
var re = brackets.makeRe(pattern);
while (i < len) {
var ele = arr[i++];
if (!re.test(ele)) {
continue;
}
res.splice(i, 1);
}
return res;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 9.52% | (2 / 21) | 0% | (0 / 16) | 0% | (0 / 1) | 10.53% | (2 / 19) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | 1 1 | /*!
* expand-range <https://github.com/jonschlinkert/expand-range>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
var fill = require('fill-range');
module.exports = function expandRange(str, options, fn) {
if (typeof str !== 'string') {
throw new TypeError('expand-range expects a string.');
}
if (typeof options === 'function') {
fn = options;
options = {};
}
if (typeof options === 'boolean') {
options = {};
options.makeRe = true;
}
// create arguments to pass to fill-range
var opts = options || {};
var args = str.split('..');
var len = args.length;
if (len > 3) { return str; }
// if only one argument, it can't expand so return it
if (len === 1) { return args; }
// if `true`, tell fill-range to regexify the string
if (typeof fn === 'boolean' && fn === true) {
opts.makeRe = true;
}
args.push(opts);
return fill.apply(null, args.concat(fn));
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 15.25% | (9 / 59) | 0% | (0 / 30) | 0% | (0 / 7) | 15.52% | (9 / 58) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | 1 1 1 1 1 1 1 1 1 | /*!
* extglob <https://github.com/jonschlinkert/extglob>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
/**
* Module dependencies
*/
var isExtglob = require('is-extglob');
var re, cache = {};
/**
* Expose `extglob`
*/
module.exports = extglob;
/**
* Convert the given extglob `string` to a regex-compatible
* string.
*
* ```js
* var extglob = require('extglob');
* extglob('!(a?(b))');
* //=> '(?!a(?:b)?)[^/]*?'
* ```
*
* @param {String} `str` The string to convert.
* @param {Object} `options`
* @option {Boolean} [options] `esc` If `false` special characters will not be escaped. Defaults to `true`.
* @option {Boolean} [options] `regex` If `true` a regular expression is returned instead of a string.
* @return {String}
* @api public
*/
function extglob(str, opts) {
opts = opts || {};
var o = {}, i = 0;
// fix common character reversals
// '*!(.js)' => '*.!(js)'
str = str.replace(/!\(([^\w*()])/g, '$1!(');
// support file extension negation
str = str.replace(/([*\/])\.!\([*]\)/g, function (m, ch) {
if (ch === '/') {
return escape('\\/[^.]+');
}
return escape('[^.]+');
});
// create a unique key for caching by
// combining the string and options
var key = str
+ String(!!opts.regex)
+ String(!!opts.contains)
+ String(!!opts.escape);
if (cache.hasOwnProperty(key)) {
return cache[key];
}
if (!(re instanceof RegExp)) {
re = regex();
}
opts.negate = false;
var m;
while (m = re.exec(str)) {
var prefix = m[1];
var inner = m[3];
if (prefix === '!') {
opts.negate = true;
}
var id = '__EXTGLOB_' + (i++) + '__';
// use the prefix of the _last_ (outtermost) pattern
o[id] = wrap(inner, prefix, opts.escape);
str = str.split(m[0]).join(id);
}
var keys = Object.keys(o);
var len = keys.length;
// we have to loop again to allow us to convert
// patterns in reverse order (starting with the
// innermost/last pattern first)
while (len--) {
var prop = keys[len];
str = str.split(prop).join(o[prop]);
}
var result = opts.regex
? toRegex(str, opts.contains, opts.negate)
: str;
result = result.split('.').join('\\.');
// cache the result and return it
return (cache[key] = result);
}
/**
* Convert `string` to a regex string.
*
* @param {String} `str`
* @param {String} `prefix` Character that determines how to wrap the string.
* @param {Boolean} `esc` If `false` special characters will not be escaped. Defaults to `true`.
* @return {String}
*/
function wrap(inner, prefix, esc) {
if (esc) inner = escape(inner);
switch (prefix) {
case '!':
return '(?!' + inner + ')[^/]' + (esc ? '%%%~' : '*?');
case '@':
return '(?:' + inner + ')';
case '+':
return '(?:' + inner + ')+';
case '*':
return '(?:' + inner + ')' + (esc ? '%%' : '*')
case '?':
return '(?:' + inner + '|)';
default:
return inner;
}
}
function escape(str) {
str = str.split('*').join('[^/]%%%~');
str = str.split('.').join('\\.');
return str;
}
/**
* extglob regex.
*/
function regex() {
return /(\\?[@?!+*$]\\?)(\(([^()]*?)\))/;
}
/**
* Negation regex
*/
function negate(str) {
return '(?!^' + str + ').*$';
}
/**
* Create the regex to do the matching. If
* the leading character in the `pattern` is `!`
* a negation regex is returned.
*
* @param {String} `pattern`
* @param {Boolean} `contains` Allow loose matching.
* @param {Boolean} `isNegated` True if the pattern is a negation pattern.
*/
function toRegex(pattern, contains, isNegated) {
var prefix = contains ? '^' : '';
var after = contains ? '$' : '';
pattern = ('(?:' + pattern + ')' + after);
if (isNegated) {
pattern = prefix + negate(pattern);
}
return new RegExp(prefix + pattern);
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (1 / 2) | 100% | (0 / 0) | 0% | (0 / 1) | 50% | (1 / 2) |
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 | /*! * filename-regex <https://github.com/regexps/filename-regex> * * Copyright (c) 2014-2015, Jon Schlinkert * Licensed under the MIT license. */ module.exports = function filenameRegex() { return /([^\\\/]+)$/; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 12.57% | (22 / 175) | 0% | (0 / 165) | 0% | (0 / 17) | 13.5% | (22 / 163) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*!
* fill-range <https://github.com/jonschlinkert/fill-range>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var isObject = require('isobject');
var isNumber = require('is-number');
var randomize = require('randomatic');
var repeatStr = require('repeat-string');
var repeat = require('repeat-element');
/**
* Expose `fillRange`
*/
module.exports = fillRange;
/**
* Return a range of numbers or letters.
*
* @param {String} `a` Start of the range
* @param {String} `b` End of the range
* @param {String} `step` Increment or decrement to use.
* @param {Function} `fn` Custom function to modify each element in the range.
* @return {Array}
*/
function fillRange(a, b, step, options, fn) {
if (a == null || b == null) {
throw new Error('fill-range expects the first and second args to be strings.');
}
if (typeof step === 'function') {
fn = step; options = {}; step = null;
}
if (typeof options === 'function') {
fn = options; options = {};
}
if (isObject(step)) {
options = step; step = '';
}
var expand, regex = false, sep = '';
var opts = options || {};
if (typeof opts.silent === 'undefined') {
opts.silent = true;
}
step = step || opts.step;
// store a ref to unmodified arg
var origA = a, origB = b;
b = (b.toString() === '-0') ? 0 : b;
if (opts.optimize || opts.makeRe) {
step = step ? (step += '~') : step;
expand = true;
regex = true;
sep = '~';
}
// handle special step characters
if (typeof step === 'string') {
var match = stepRe().exec(step);
if (match) {
var i = match.index;
var m = match[0];
// repeat string
if (m === '+') {
return repeat(a, b);
// randomize a, `b` times
} else if (m === '?') {
return [randomize(a, b)];
// expand right, no regex reduction
} else if (m === '>') {
step = step.substr(0, i) + step.substr(i + 1);
expand = true;
// expand to an array, or if valid create a reduced
// string for a regex logic `or`
} else if (m === '|') {
step = step.substr(0, i) + step.substr(i + 1);
expand = true;
regex = true;
sep = m;
// expand to an array, or if valid create a reduced
// string for a regex range
} else if (m === '~') {
step = step.substr(0, i) + step.substr(i + 1);
expand = true;
regex = true;
sep = m;
}
} else if (!isNumber(step)) {
if (!opts.silent) {
throw new TypeError('fill-range: invalid step.');
}
return null;
}
}
if (/[.&*()[\]^%$#@!]/.test(a) || /[.&*()[\]^%$#@!]/.test(b)) {
if (!opts.silent) {
throw new RangeError('fill-range: invalid range arguments.');
}
return null;
}
// has neither a letter nor number, or has both letters and numbers
// this needs to be after the step logic
if (!noAlphaNum(a) || !noAlphaNum(b) || hasBoth(a) || hasBoth(b)) {
if (!opts.silent) {
throw new RangeError('fill-range: invalid range arguments.');
}
return null;
}
// validate arguments
var isNumA = isNumber(zeros(a));
var isNumB = isNumber(zeros(b));
if ((!isNumA && isNumB) || (isNumA && !isNumB)) {
if (!opts.silent) {
throw new TypeError('fill-range: first range argument is incompatible with second.');
}
return null;
}
// by this point both are the same, so we
// can use A to check going forward.
var isNum = isNumA;
var num = formatStep(step);
// is the range alphabetical? or numeric?
if (isNum) {
// if numeric, coerce to an integer
a = +a; b = +b;
} else {
// otherwise, get the charCode to expand alpha ranges
a = a.charCodeAt(0);
b = b.charCodeAt(0);
}
// is the pattern descending?
var isDescending = a > b;
// don't create a character class if the args are < 0
if (a < 0 || b < 0) {
expand = false;
regex = false;
}
// detect padding
var padding = isPadded(origA, origB);
var res, pad, arr = [];
var ii = 0;
// character classes, ranges and logical `or`
if (regex) {
if (shouldExpand(a, b, num, isNum, padding, opts)) {
// make sure the correct separator is used
if (sep === '|' || sep === '~') {
sep = detectSeparator(a, b, num, isNum, isDescending);
}
return wrap([origA, origB], sep, opts);
}
}
while (isDescending ? (a >= b) : (a <= b)) {
if (padding && isNum) {
pad = padding(a);
}
// custom function
if (typeof fn === 'function') {
res = fn(a, isNum, pad, ii++);
// letters
} else if (!isNum) {
if (regex && isInvalidChar(a)) {
res = null;
} else {
res = String.fromCharCode(a);
}
// numbers
} else {
res = formatPadding(a, pad);
}
// add result to the array, filtering any nulled values
if (res !== null) arr.push(res);
// increment or decrement
if (isDescending) {
a -= num;
} else {
a += num;
}
}
// now that the array is expanded, we need to handle regex
// character classes, ranges or logical `or` that wasn't
// already handled before the loop
if ((regex || expand) && !opts.noexpand) {
// make sure the correct separator is used
if (sep === '|' || sep === '~') {
sep = detectSeparator(a, b, num, isNum, isDescending);
}
if (arr.length === 1 || a < 0 || b < 0) { return arr; }
return wrap(arr, sep, opts);
}
return arr;
}
/**
* Wrap the string with the correct regex
* syntax.
*/
function wrap(arr, sep, opts) {
if (sep === '~') { sep = '-'; }
var str = arr.join(sep);
var pre = opts && opts.regexPrefix;
// regex logical `or`
if (sep === '|') {
str = pre ? pre + str : str;
str = '(' + str + ')';
}
// regex character class
if (sep === '-') {
str = (pre && pre === '^')
? pre + str
: str;
str = '[' + str + ']';
}
return [str];
}
/**
* Check for invalid characters
*/
function isCharClass(a, b, step, isNum, isDescending) {
if (isDescending) { return false; }
if (isNum) { return a <= 9 && b <= 9; }
if (a < b) { return step === 1; }
return false;
}
/**
* Detect the correct separator to use
*/
function shouldExpand(a, b, num, isNum, padding, opts) {
if (isNum && (a > 9 || b > 9)) { return false; }
return !padding && num === 1 && a < b;
}
/**
* Detect the correct separator to use
*/
function detectSeparator(a, b, step, isNum, isDescending) {
var isChar = isCharClass(a, b, step, isNum, isDescending);
if (!isChar) {
return '|';
}
return '~';
}
/**
* Correctly format the step based on type
*/
function formatStep(step) {
return Math.abs(step >> 0) || 1;
}
/**
* Format padding, taking leading `-` into account
*/
function formatPadding(ch, pad) {
var res = pad ? pad + ch : ch;
if (pad && ch.toString().charAt(0) === '-') {
res = '-' + pad + ch.toString().substr(1);
}
return res.toString();
}
/**
* Check for invalid characters
*/
function isInvalidChar(str) {
var ch = toStr(str);
return ch === '\\'
|| ch === '['
|| ch === ']'
|| ch === '^'
|| ch === '('
|| ch === ')'
|| ch === '`';
}
/**
* Convert to a string from a charCode
*/
function toStr(ch) {
return String.fromCharCode(ch);
}
/**
* Step regex
*/
function stepRe() {
return /\?|>|\||\+|\~/g;
}
/**
* Return true if `val` has either a letter
* or a number
*/
function noAlphaNum(val) {
return /[a-z0-9]/i.test(val);
}
/**
* Return true if `val` has both a letter and
* a number (invalid)
*/
function hasBoth(val) {
return /[a-z][0-9]|[0-9][a-z]/i.test(val);
}
/**
* Normalize zeros for checks
*/
function zeros(val) {
if (/^-*0+$/.test(val.toString())) {
return '0';
}
return val;
}
/**
* Return true if `val` has leading zeros,
* or a similar valid pattern.
*/
function hasZeros(val) {
return /[^.]\.|^-*0+[0-9]/.test(val);
}
/**
* If the string is padded, returns a curried function with
* the a cached padding string, or `false` if no padding.
*
* @param {*} `origA` String or number.
* @return {String|Boolean}
*/
function isPadded(origA, origB) {
if (hasZeros(origA) || hasZeros(origB)) {
var alen = length(origA);
var blen = length(origB);
var len = alen >= blen
? alen
: blen;
return function (a) {
return repeatStr('0', len - length(a));
};
}
return false;
}
/**
* Get the string length of `val`
*/
function length(val) {
return val.toString().length;
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 26.32% | (5 / 19) | 0% | (0 / 12) | 0% | (0 / 2) | 26.32% | (5 / 19) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 1 1 1 1 1 | 'use strict';
var path = require('path');
var commonDir = require('commondir');
var pkgDir = require('pkg-dir');
var mkdirp = require('mkdirp');
module.exports = function (options) {
var name = options.name;
var dir = options.cwd;
if (options.files) {
dir = commonDir(dir, options.files);
} else {
dir = dir || process.cwd();
}
dir = pkgDir.sync(dir);
if (dir) {
dir = path.join(dir, 'node_modules', '.cache', name);
if (dir && options.create) {
mkdirp.sync(dir);
}
if (options.thunk) {
return function () {
return path.join.apply(path, [dir].concat(Array.prototype.slice.call(arguments)));
};
}
}
return dir;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 24.14% | (7 / 29) | 0% | (0 / 12) | 0% | (0 / 7) | 24.14% | (7 / 29) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 1 1 1 1 1 1 1 | 'use strict';
var path = require('path');
var pathExists = require('path-exists');
var Promise = require('pinkie-promise');
function splitPath(x) {
return path.resolve(x || '').split(path.sep);
}
function join(parts, filename) {
return path.resolve(parts.join(path.sep) + path.sep, filename);
}
module.exports = function (filename, opts) {
opts = opts || {};
var parts = splitPath(opts.cwd);
return new Promise(function (resolve) {
(function find() {
var fp = join(parts, filename);
pathExists(fp).then(function (exists) {
if (exists) {
resolve(fp);
} else if (parts.pop()) {
find();
} else {
resolve(null);
}
});
})();
});
};
module.exports.sync = function (filename, opts) {
opts = opts || {};
var parts = splitPath(opts.cwd);
var len = parts.length;
while (len--) {
var fp = join(parts, filename);
if (pathExists.sync(fp)) {
return fp;
}
parts.pop();
}
return null;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 25% | (1 / 4) | 0% | (0 / 2) | 0% | (0 / 1) | 25% | (1 / 4) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 1 | /*! * for-in <https://github.com/jonschlinkert/for-in> * * Copyright (c) 2014-2017, Jon Schlinkert. * Released under the MIT License. */ 'use strict'; module.exports = function forIn(obj, fn, thisArg) { for (var key in obj) { if (fn.call(thisArg, obj[key], key, obj) === false) { break; } } }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (3 / 6) | 0% | (0 / 2) | 0% | (0 / 2) | 50% | (3 / 6) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 1 1 1 | /*!
* for-own <https://github.com/jonschlinkert/for-own>
*
* Copyright (c) 2014-2017, Jon Schlinkert.
* Released under the MIT License.
*/
'use strict';
var forIn = require('for-in');
var hasOwn = Object.prototype.hasOwnProperty;
module.exports = function forOwn(obj, fn, thisArg) {
forIn(obj, function(val, key) {
if (hasOwn.call(obj, key)) {
return fn.call(thisArg, obj[key], key, obj);
}
});
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | module.exports = realpath
realpath.realpath = realpath
realpath.sync = realpathSync
realpath.realpathSync = realpathSync
realpath.monkeypatch = monkeypatch
realpath.unmonkeypatch = unmonkeypatch
var fs = require('fs')
var origRealpath = fs.realpath
var origRealpathSync = fs.realpathSync
var version = process.version
var ok = /^v[0-5]\./.test(version)
var old = require('./old.js')
function newError (er) {
return er && er.syscall === 'realpath' && (
er.code === 'ELOOP' ||
er.code === 'ENOMEM' ||
er.code === 'ENAMETOOLONG'
)
}
function realpath (p, cache, cb) {
if (ok) {
return origRealpath(p, cache, cb)
}
if (typeof cache === 'function') {
cb = cache
cache = null
}
origRealpath(p, cache, function (er, result) {
if (newError(er)) {
old.realpath(p, cache, cb)
} else {
cb(er, result)
}
})
}
function realpathSync (p, cache) {
if (ok) {
return origRealpathSync(p, cache)
}
try {
return origRealpathSync(p, cache)
} catch (er) {
if (newError(er)) {
return old.realpathSync(p, cache)
} else {
throw er
}
}
}
function monkeypatch () {
fs.realpath = realpath
fs.realpathSync = realpathSync
}
function unmonkeypatch () {
fs.realpath = origRealpath
fs.realpathSync = origRealpathSync
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | // Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var pathModule = require('path');
var isWindows = process.platform === 'win32';
var fs = require('fs');
// JavaScript implementation of realpath, ported from node pre-v6
var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
function rethrow() {
// Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
// is fairly slow to generate.
var callback;
if (DEBUG) {
var backtrace = new Error;
callback = debugCallback;
} else
callback = missingCallback;
return callback;
function debugCallback(err) {
if (err) {
backtrace.message = err.message;
err = backtrace;
missingCallback(err);
}
}
function missingCallback(err) {
if (err) {
if (process.throwDeprecation)
throw err; // Forgot a callback but don't know where? Use NODE_DEBUG=fs
else if (!process.noDeprecation) {
var msg = 'fs: missing callback ' + (err.stack || err.message);
if (process.traceDeprecation)
console.trace(msg);
else
console.error(msg);
}
}
}
}
function maybeCallback(cb) {
return typeof cb === 'function' ? cb : rethrow();
}
var normalize = pathModule.normalize;
// Regexp that finds the next partion of a (partial) path
// result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
Iif (isWindows) {
var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
} else {
var nextPartRe = /(.*?)(?:[\/]+|$)/g;
}
// Regex to find the device root, including trailing slash. E.g. 'c:\\'.
Iif (isWindows) {
var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
} else {
var splitRootRe = /^[\/]*/;
}
exports.realpathSync = function realpathSync(p, cache) {
// make p is absolute
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return cache[p];
}
var original = p,
seenLinks = {},
knownHard = {};
// current character position in p
var pos;
// the partial path so far, including a trailing slash if any
var current;
// the partial path without a trailing slash (except when pointing at a root)
var base;
// the partial path scanned in the previous round, with slash
var previous;
start();
function start() {
// Skip over roots
var m = splitRootRe.exec(p);
pos = m[0].length;
current = m[0];
base = m[0];
previous = '';
// On windows, check that the root exists. On unix there is no need.
if (isWindows && !knownHard[base]) {
fs.lstatSync(base);
knownHard[base] = true;
}
}
// walk down the path, swapping out linked pathparts for their real
// values
// NB: p.length changes.
while (pos < p.length) {
// find the next part
nextPartRe.lastIndex = pos;
var result = nextPartRe.exec(p);
previous = current;
current += result[0];
base = previous + result[1];
pos = nextPartRe.lastIndex;
// continue if not a symlink
if (knownHard[base] || (cache && cache[base] === base)) {
continue;
}
var resolvedLink;
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
// some known symbolic link. no need to stat again.
resolvedLink = cache[base];
} else {
var stat = fs.lstatSync(base);
if (!stat.isSymbolicLink()) {
knownHard[base] = true;
if (cache) cache[base] = base;
continue;
}
// read the link if it wasn't read before
// dev/ino always return 0 on windows, so skip the check.
var linkTarget = null;
if (!isWindows) {
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
if (seenLinks.hasOwnProperty(id)) {
linkTarget = seenLinks[id];
}
}
if (linkTarget === null) {
fs.statSync(base);
linkTarget = fs.readlinkSync(base);
}
resolvedLink = pathModule.resolve(previous, linkTarget);
// track this, if given a cache.
if (cache) cache[base] = resolvedLink;
if (!isWindows) seenLinks[id] = linkTarget;
}
// resolve the link, then start over
p = pathModule.resolve(resolvedLink, p.slice(pos));
start();
}
if (cache) cache[original] = p;
return p;
};
exports.realpath = function realpath(p, cache, cb) {
if (typeof cb !== 'function') {
cb = maybeCallback(cache);
cache = null;
}
// make p is absolute
p = pathModule.resolve(p);
if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
return process.nextTick(cb.bind(null, null, cache[p]));
}
var original = p,
seenLinks = {},
knownHard = {};
// current character position in p
var pos;
// the partial path so far, including a trailing slash if any
var current;
// the partial path without a trailing slash (except when pointing at a root)
var base;
// the partial path scanned in the previous round, with slash
var previous;
start();
function start() {
// Skip over roots
var m = splitRootRe.exec(p);
pos = m[0].length;
current = m[0];
base = m[0];
previous = '';
// On windows, check that the root exists. On unix there is no need.
if (isWindows && !knownHard[base]) {
fs.lstat(base, function(err) {
if (err) return cb(err);
knownHard[base] = true;
LOOP();
});
} else {
process.nextTick(LOOP);
}
}
// walk down the path, swapping out linked pathparts for their real
// values
function LOOP() {
// stop if scanned past end of path
if (pos >= p.length) {
if (cache) cache[original] = p;
return cb(null, p);
}
// find the next part
nextPartRe.lastIndex = pos;
var result = nextPartRe.exec(p);
previous = current;
current += result[0];
base = previous + result[1];
pos = nextPartRe.lastIndex;
// continue if not a symlink
if (knownHard[base] || (cache && cache[base] === base)) {
return process.nextTick(LOOP);
}
if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
// known symbolic link. no need to stat again.
return gotResolvedLink(cache[base]);
}
return fs.lstat(base, gotStat);
}
function gotStat(err, stat) {
if (err) return cb(err);
// if not a symlink, skip to the next path part
if (!stat.isSymbolicLink()) {
knownHard[base] = true;
if (cache) cache[base] = base;
return process.nextTick(LOOP);
}
// stat & read the link if not read before
// call gotTarget as soon as the link target is known
// dev/ino always return 0 on windows, so skip the check.
if (!isWindows) {
var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
if (seenLinks.hasOwnProperty(id)) {
return gotTarget(null, seenLinks[id], base);
}
}
fs.stat(base, function(err) {
if (err) return cb(err);
fs.readlink(base, function(err, target) {
if (!isWindows) seenLinks[id] = target;
gotTarget(err, target);
});
});
}
function gotTarget(err, target, base) {
if (err) return cb(err);
var resolvedLink = pathModule.resolve(previous, target);
if (cache) cache[base] = resolvedLink;
gotResolvedLink(resolvedLink);
}
function gotResolvedLink(resolvedLink) {
// resolve the link, then start over
p = pathModule.resolve(resolvedLink, p.slice(pos));
start();
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 19.23% | (5 / 26) | 0% | (0 / 16) | 0% | (0 / 2) | 20% | (5 / 25) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 1 1 1 1 1 | /*!
* glob-base <https://github.com/jonschlinkert/glob-base>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var path = require('path');
var parent = require('glob-parent');
var isGlob = require('is-glob');
module.exports = function globBase(pattern) {
if (typeof pattern !== 'string') {
throw new TypeError('glob-base expects a string.');
}
var res = {};
res.base = parent(pattern);
res.isGlob = isGlob(pattern);
if (res.base !== '.') {
res.glob = pattern.substr(res.base.length);
if (res.glob.charAt(0) === '/') {
res.glob = res.glob.substr(1);
}
} else {
res.glob = pattern;
}
if (!res.isGlob) {
res.base = dirname(pattern);
res.glob = res.base !== '.'
? pattern.substr(res.base.length)
: pattern;
}
if (res.glob.substr(0, 2) === './') {
res.glob = res.glob.substr(2);
}
if (res.glob.charAt(0) === '/') {
res.glob = res.glob.substr(1);
}
return res;
};
function dirname(glob) {
if (glob.slice(-1) === '/') return glob;
return path.dirname(glob);
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 42.86% | (3 / 7) | 100% | (0 / 0) | 0% | (0 / 1) | 50% | (3 / 6) |
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 1 1 | 'use strict';
var path = require('path');
var isglob = require('is-glob');
module.exports = function globParent(str) {
str += 'a'; // preserves full path in case of trailing path separator
do {str = path.dirname(str)} while (isglob(str));
return str;
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | exports.alphasort = alphasort exports.alphasorti = alphasorti exports.setopts = setopts exports.ownProp = ownProp exports.makeAbs = makeAbs exports.finish = finish exports.mark = mark exports.isIgnored = isIgnored exports.childrenIgnored = childrenIgnored function ownProp (obj, field) { return Object.prototype.hasOwnProperty.call(obj, field) } var path = require("path") var minimatch = require("minimatch") var isAbsolute = require("path-is-absolute") var Minimatch = minimatch.Minimatch function alphasorti (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()) } function alphasort (a, b) { return a.localeCompare(b) } function setupIgnores (self, options) { self.ignore = options.ignore || [] if (!Array.isArray(self.ignore)) self.ignore = [self.ignore] if (self.ignore.length) { self.ignore = self.ignore.map(ignoreMap) } } // ignore patterns are always in dot:true mode. function ignoreMap (pattern) { var gmatcher = null if (pattern.slice(-3) === '/**') { var gpattern = pattern.replace(/(\/\*\*)+$/, '') gmatcher = new Minimatch(gpattern, { dot: true }) } return { matcher: new Minimatch(pattern, { dot: true }), gmatcher: gmatcher } } function setopts (self, pattern, options) { if (!options) options = {} // base-matching: just use globstar for that. if (options.matchBase && -1 === pattern.indexOf("/")) { if (options.noglobstar) { throw new Error("base matching requires globstar") } pattern = "**/" + pattern } self.silent = !!options.silent self.pattern = pattern self.strict = options.strict !== false self.realpath = !!options.realpath self.realpathCache = options.realpathCache || Object.create(null) self.follow = !!options.follow self.dot = !!options.dot self.mark = !!options.mark self.nodir = !!options.nodir if (self.nodir) self.mark = true self.sync = !!options.sync self.nounique = !!options.nounique self.nonull = !!options.nonull self.nosort = !!options.nosort self.nocase = !!options.nocase self.stat = !!options.stat self.noprocess = !!options.noprocess self.absolute = !!options.absolute self.maxLength = options.maxLength || Infinity self.cache = options.cache || Object.create(null) self.statCache = options.statCache || Object.create(null) self.symlinks = options.symlinks || Object.create(null) setupIgnores(self, options) self.changedCwd = false var cwd = process.cwd() if (!ownProp(options, "cwd")) self.cwd = cwd else { self.cwd = path.resolve(options.cwd) self.changedCwd = self.cwd !== cwd } self.root = options.root || path.resolve(self.cwd, "/") self.root = path.resolve(self.root) if (process.platform === "win32") self.root = self.root.replace(/\\/g, "/") // TODO: is an absolute `cwd` supposed to be resolved against `root`? // e.g. { cwd: '/test', root: __dirname } === path.join(__dirname, '/test') self.cwdAbs = isAbsolute(self.cwd) ? self.cwd : makeAbs(self, self.cwd) if (process.platform === "win32") self.cwdAbs = self.cwdAbs.replace(/\\/g, "/") self.nomount = !!options.nomount // disable comments and negation in Minimatch. // Note that they are not supported in Glob itself anyway. options.nonegate = true options.nocomment = true self.minimatch = new Minimatch(pattern, options) self.options = self.minimatch.options } function finish (self) { var nou = self.nounique var all = nou ? [] : Object.create(null) for (var i = 0, l = self.matches.length; i < l; i ++) { var matches = self.matches[i] if (!matches || Object.keys(matches).length === 0) { if (self.nonull) { // do like the shell, and spit out the literal glob var literal = self.minimatch.globSet[i] if (nou) all.push(literal) else all[literal] = true } } else { // had matches var m = Object.keys(matches) if (nou) all.push.apply(all, m) else m.forEach(function (m) { all[m] = true }) } } if (!nou) all = Object.keys(all) if (!self.nosort) all = all.sort(self.nocase ? alphasorti : alphasort) // at *some* point we statted all of these if (self.mark) { for (var i = 0; i < all.length; i++) { all[i] = self._mark(all[i]) } if (self.nodir) { all = all.filter(function (e) { var notDir = !(/\/$/.test(e)) var c = self.cache[e] || self.cache[makeAbs(self, e)] if (notDir && c) notDir = c !== 'DIR' && !Array.isArray(c) return notDir }) } } if (self.ignore.length) all = all.filter(function(m) { return !isIgnored(self, m) }) self.found = all } function mark (self, p) { var abs = makeAbs(self, p) var c = self.cache[abs] var m = p if (c) { var isDir = c === 'DIR' || Array.isArray(c) var slash = p.slice(-1) === '/' if (isDir && !slash) m += '/' else if (!isDir && slash) m = m.slice(0, -1) if (m !== p) { var mabs = makeAbs(self, m) self.statCache[mabs] = self.statCache[abs] self.cache[mabs] = self.cache[abs] } } return m } // lotta situps... function makeAbs (self, f) { var abs = f if (f.charAt(0) === '/') { abs = path.join(self.root, f) } else if (isAbsolute(f) || f === '') { abs = f } else if (self.changedCwd) { abs = path.resolve(self.cwd, f) } else { abs = path.resolve(f) } if (process.platform === 'win32') abs = abs.replace(/\\/g, '/') return abs } // Return true, if pattern ends with globstar '**', for the accompanying parent directory. // Ex:- If node_modules/** is the pattern, add 'node_modules' to ignore list along with it's contents function isIgnored (self, path) { if (!self.ignore.length) return false return self.ignore.some(function(item) { return item.matcher.match(path) || !!(item.gmatcher && item.gmatcher.match(path)) }) } function childrenIgnored (self, path) { if (!self.ignore.length) return false return self.ignore.some(function(item) { return !!(item.gmatcher && item.gmatcher.match(path)) }) } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | // Approach:
//
// 1. Get the minimatch set
// 2. For each pattern in the set, PROCESS(pattern, false)
// 3. Store matches per-set, then uniq them
//
// PROCESS(pattern, inGlobStar)
// Get the first [n] items from pattern that are all strings
// Join these together. This is PREFIX.
// If there is no more remaining, then stat(PREFIX) and
// add to matches if it succeeds. END.
//
// If inGlobStar and PREFIX is symlink and points to dir
// set ENTRIES = []
// else readdir(PREFIX) as ENTRIES
// If fail, END
//
// with ENTRIES
// If pattern[n] is GLOBSTAR
// // handle the case where the globstar match is empty
// // by pruning it out, and testing the resulting pattern
// PROCESS(pattern[0..n] + pattern[n+1 .. $], false)
// // handle other cases.
// for ENTRY in ENTRIES (not dotfiles)
// // attach globstar + tail onto the entry
// // Mark that this entry is a globstar match
// PROCESS(pattern[0..n] + ENTRY + pattern[n .. $], true)
//
// else // not globstar
// for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
// Test ENTRY against pattern[n]
// If fails, continue
// If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
//
// Caveat:
// Cache all stats and readdirs results to minimize syscall. Since all
// we ever care about is existence and directory-ness, we can just keep
// `true` for files, and [children,...] for directories, or `false` for
// things that don't exist.
module.exports = glob
var fs = require('fs')
var rp = require('fs.realpath')
var minimatch = require('minimatch')
var Minimatch = minimatch.Minimatch
var inherits = require('inherits')
var EE = require('events').EventEmitter
var path = require('path')
var assert = require('assert')
var isAbsolute = require('path-is-absolute')
var globSync = require('./sync.js')
var common = require('./common.js')
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
var ownProp = common.ownProp
var inflight = require('inflight')
var util = require('util')
var childrenIgnored = common.childrenIgnored
var isIgnored = common.isIgnored
var once = require('once')
function glob (pattern, options, cb) {
if (typeof options === 'function') cb = options, options = {}
if (!options) options = {}
if (options.sync) {
if (cb)
throw new TypeError('callback provided to sync glob')
return globSync(pattern, options)
}
return new Glob(pattern, options, cb)
}
glob.sync = globSync
var GlobSync = glob.GlobSync = globSync.GlobSync
// old api surface
glob.glob = glob
function extend (origin, add) {
if (add === null || typeof add !== 'object') {
return origin
}
var keys = Object.keys(add)
var i = keys.length
while (i--) {
origin[keys[i]] = add[keys[i]]
}
return origin
}
glob.hasMagic = function (pattern, options_) {
var options = extend({}, options_)
options.noprocess = true
var g = new Glob(pattern, options)
var set = g.minimatch.set
if (!pattern)
return false
if (set.length > 1)
return true
for (var j = 0; j < set[0].length; j++) {
if (typeof set[0][j] !== 'string')
return true
}
return false
}
glob.Glob = Glob
inherits(Glob, EE)
function Glob (pattern, options, cb) {
if (typeof options === 'function') {
cb = options
options = null
}
if (options && options.sync) {
if (cb)
throw new TypeError('callback provided to sync glob')
return new GlobSync(pattern, options)
}
if (!(this instanceof Glob))
return new Glob(pattern, options, cb)
setopts(this, pattern, options)
this._didRealPath = false
// process each pattern in the minimatch set
var n = this.minimatch.set.length
// The matches are stored as {<filename>: true,...} so that
// duplicates are automagically pruned.
// Later, we do an Object.keys() on these.
// Keep them as a list so we can fill in when nonull is set.
this.matches = new Array(n)
if (typeof cb === 'function') {
cb = once(cb)
this.on('error', cb)
this.on('end', function (matches) {
cb(null, matches)
})
}
var self = this
var n = this.minimatch.set.length
this._processing = 0
this.matches = new Array(n)
this._emitQueue = []
this._processQueue = []
this.paused = false
if (this.noprocess)
return this
if (n === 0)
return done()
var sync = true
for (var i = 0; i < n; i ++) {
this._process(this.minimatch.set[i], i, false, done)
}
sync = false
function done () {
--self._processing
if (self._processing <= 0) {
if (sync) {
process.nextTick(function () {
self._finish()
})
} else {
self._finish()
}
}
}
}
Glob.prototype._finish = function () {
assert(this instanceof Glob)
if (this.aborted)
return
if (this.realpath && !this._didRealpath)
return this._realpath()
common.finish(this)
this.emit('end', this.found)
}
Glob.prototype._realpath = function () {
if (this._didRealpath)
return
this._didRealpath = true
var n = this.matches.length
if (n === 0)
return this._finish()
var self = this
for (var i = 0; i < this.matches.length; i++)
this._realpathSet(i, next)
function next () {
if (--n === 0)
self._finish()
}
}
Glob.prototype._realpathSet = function (index, cb) {
var matchset = this.matches[index]
if (!matchset)
return cb()
var found = Object.keys(matchset)
var self = this
var n = found.length
if (n === 0)
return cb()
var set = this.matches[index] = Object.create(null)
found.forEach(function (p, i) {
// If there's a problem with the stat, then it means that
// one or more of the links in the realpath couldn't be
// resolved. just return the abs value in that case.
p = self._makeAbs(p)
rp.realpath(p, self.realpathCache, function (er, real) {
if (!er)
set[real] = true
else if (er.syscall === 'stat')
set[p] = true
else
self.emit('error', er) // srsly wtf right here
if (--n === 0) {
self.matches[index] = set
cb()
}
})
})
}
Glob.prototype._mark = function (p) {
return common.mark(this, p)
}
Glob.prototype._makeAbs = function (f) {
return common.makeAbs(this, f)
}
Glob.prototype.abort = function () {
this.aborted = true
this.emit('abort')
}
Glob.prototype.pause = function () {
if (!this.paused) {
this.paused = true
this.emit('pause')
}
}
Glob.prototype.resume = function () {
if (this.paused) {
this.emit('resume')
this.paused = false
if (this._emitQueue.length) {
var eq = this._emitQueue.slice(0)
this._emitQueue.length = 0
for (var i = 0; i < eq.length; i ++) {
var e = eq[i]
this._emitMatch(e[0], e[1])
}
}
if (this._processQueue.length) {
var pq = this._processQueue.slice(0)
this._processQueue.length = 0
for (var i = 0; i < pq.length; i ++) {
var p = pq[i]
this._processing--
this._process(p[0], p[1], p[2], p[3])
}
}
}
}
Glob.prototype._process = function (pattern, index, inGlobStar, cb) {
assert(this instanceof Glob)
assert(typeof cb === 'function')
if (this.aborted)
return
this._processing++
if (this.paused) {
this._processQueue.push([pattern, index, inGlobStar, cb])
return
}
//console.error('PROCESS %d', this._processing, pattern)
// Get the first [n] parts of pattern that are all strings.
var n = 0
while (typeof pattern[n] === 'string') {
n ++
}
// now n is the index of the first one that is *not* a string.
// see if there's anything else
var prefix
switch (n) {
// if not, then this is rather simple
case pattern.length:
this._processSimple(pattern.join('/'), index, cb)
return
case 0:
// pattern *starts* with some non-trivial item.
// going to readdir(cwd), but not include the prefix in matches.
prefix = null
break
default:
// pattern has some string bits in the front.
// whatever it starts with, whether that's 'absolute' like /foo/bar,
// or 'relative' like '../baz'
prefix = pattern.slice(0, n).join('/')
break
}
var remain = pattern.slice(n)
// get the list of entries.
var read
if (prefix === null)
read = '.'
else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {
if (!prefix || !isAbsolute(prefix))
prefix = '/' + prefix
read = prefix
} else
read = prefix
var abs = this._makeAbs(read)
//if ignored, skip _processing
if (childrenIgnored(this, read))
return cb()
var isGlobStar = remain[0] === minimatch.GLOBSTAR
if (isGlobStar)
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar, cb)
else
this._processReaddir(prefix, read, abs, remain, index, inGlobStar, cb)
}
Glob.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar, cb) {
var self = this
this._readdir(abs, inGlobStar, function (er, entries) {
return self._processReaddir2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
})
}
Glob.prototype._processReaddir2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
// if the abs isn't a dir, then nothing can match!
if (!entries)
return cb()
// It will only match dot entries if it starts with a dot, or if
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
var pn = remain[0]
var negate = !!this.minimatch.negate
var rawGlob = pn._glob
var dotOk = this.dot || rawGlob.charAt(0) === '.'
var matchedEntries = []
for (var i = 0; i < entries.length; i++) {
var e = entries[i]
if (e.charAt(0) !== '.' || dotOk) {
var m
if (negate && !prefix) {
m = !e.match(pn)
} else {
m = e.match(pn)
}
if (m)
matchedEntries.push(e)
}
}
//console.error('prd2', prefix, entries, remain[0]._glob, matchedEntries)
var len = matchedEntries.length
// If there are no matched entries, then nothing matches.
if (len === 0)
return cb()
// if this is the last remaining pattern bit, then no need for
// an additional stat *unless* the user has specified mark or
// stat explicitly. We know they exist, since readdir returned
// them.
if (remain.length === 1 && !this.mark && !this.stat) {
if (!this.matches[index])
this.matches[index] = Object.create(null)
for (var i = 0; i < len; i ++) {
var e = matchedEntries[i]
if (prefix) {
if (prefix !== '/')
e = prefix + '/' + e
else
e = prefix + e
}
if (e.charAt(0) === '/' && !this.nomount) {
e = path.join(this.root, e)
}
this._emitMatch(index, e)
}
// This was the last one, and no stats were needed
return cb()
}
// now test all matched entries as stand-ins for that part
// of the pattern.
remain.shift()
for (var i = 0; i < len; i ++) {
var e = matchedEntries[i]
var newPattern
if (prefix) {
if (prefix !== '/')
e = prefix + '/' + e
else
e = prefix + e
}
this._process([e].concat(remain), index, inGlobStar, cb)
}
cb()
}
Glob.prototype._emitMatch = function (index, e) {
if (this.aborted)
return
if (isIgnored(this, e))
return
if (this.paused) {
this._emitQueue.push([index, e])
return
}
var abs = isAbsolute(e) ? e : this._makeAbs(e)
if (this.mark)
e = this._mark(e)
if (this.absolute)
e = abs
if (this.matches[index][e])
return
if (this.nodir) {
var c = this.cache[abs]
if (c === 'DIR' || Array.isArray(c))
return
}
this.matches[index][e] = true
var st = this.statCache[abs]
if (st)
this.emit('stat', e, st)
this.emit('match', e)
}
Glob.prototype._readdirInGlobStar = function (abs, cb) {
if (this.aborted)
return
// follow all symlinked directories forever
// just proceed as if this is a non-globstar situation
if (this.follow)
return this._readdir(abs, false, cb)
var lstatkey = 'lstat\0' + abs
var self = this
var lstatcb = inflight(lstatkey, lstatcb_)
if (lstatcb)
fs.lstat(abs, lstatcb)
function lstatcb_ (er, lstat) {
if (er && er.code === 'ENOENT')
return cb()
var isSym = lstat && lstat.isSymbolicLink()
self.symlinks[abs] = isSym
// If it's not a symlink or a dir, then it's definitely a regular file.
// don't bother doing a readdir in that case.
if (!isSym && lstat && !lstat.isDirectory()) {
self.cache[abs] = 'FILE'
cb()
} else
self._readdir(abs, false, cb)
}
}
Glob.prototype._readdir = function (abs, inGlobStar, cb) {
if (this.aborted)
return
cb = inflight('readdir\0'+abs+'\0'+inGlobStar, cb)
if (!cb)
return
//console.error('RD %j %j', +inGlobStar, abs)
if (inGlobStar && !ownProp(this.symlinks, abs))
return this._readdirInGlobStar(abs, cb)
if (ownProp(this.cache, abs)) {
var c = this.cache[abs]
if (!c || c === 'FILE')
return cb()
if (Array.isArray(c))
return cb(null, c)
}
var self = this
fs.readdir(abs, readdirCb(this, abs, cb))
}
function readdirCb (self, abs, cb) {
return function (er, entries) {
if (er)
self._readdirError(abs, er, cb)
else
self._readdirEntries(abs, entries, cb)
}
}
Glob.prototype._readdirEntries = function (abs, entries, cb) {
if (this.aborted)
return
// if we haven't asked to stat everything, then just
// assume that everything in there exists, so we can avoid
// having to stat it a second time.
if (!this.mark && !this.stat) {
for (var i = 0; i < entries.length; i ++) {
var e = entries[i]
if (abs === '/')
e = abs + e
else
e = abs + '/' + e
this.cache[e] = true
}
}
this.cache[abs] = entries
return cb(null, entries)
}
Glob.prototype._readdirError = function (f, er, cb) {
if (this.aborted)
return
// handle errors, and cache the information
switch (er.code) {
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
case 'ENOTDIR': // totally normal. means it *does* exist.
var abs = this._makeAbs(f)
this.cache[abs] = 'FILE'
if (abs === this.cwdAbs) {
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
error.path = this.cwd
error.code = er.code
this.emit('error', error)
this.abort()
}
break
case 'ENOENT': // not terribly unusual
case 'ELOOP':
case 'ENAMETOOLONG':
case 'UNKNOWN':
this.cache[this._makeAbs(f)] = false
break
default: // some unusual error. Treat as failure.
this.cache[this._makeAbs(f)] = false
if (this.strict) {
this.emit('error', er)
// If the error is handled, then we abort
// if not, we threw out of here
this.abort()
}
if (!this.silent)
console.error('glob error', er)
break
}
return cb()
}
Glob.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar, cb) {
var self = this
this._readdir(abs, inGlobStar, function (er, entries) {
self._processGlobStar2(prefix, read, abs, remain, index, inGlobStar, entries, cb)
})
}
Glob.prototype._processGlobStar2 = function (prefix, read, abs, remain, index, inGlobStar, entries, cb) {
//console.error('pgs2', prefix, remain[0], entries)
// no entries means not a dir, so it can never have matches
// foo.txt/** doesn't match foo.txt
if (!entries)
return cb()
// test without the globstar, and with every child both below
// and replacing the globstar.
var remainWithoutGlobStar = remain.slice(1)
var gspref = prefix ? [ prefix ] : []
var noGlobStar = gspref.concat(remainWithoutGlobStar)
// the noGlobStar pattern exits the inGlobStar state
this._process(noGlobStar, index, false, cb)
var isSym = this.symlinks[abs]
var len = entries.length
// If it's a symlink, and we're in a globstar, then stop
if (isSym && inGlobStar)
return cb()
for (var i = 0; i < len; i++) {
var e = entries[i]
if (e.charAt(0) === '.' && !this.dot)
continue
// these two cases enter the inGlobStar state
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
this._process(instead, index, true, cb)
var below = gspref.concat(entries[i], remain)
this._process(below, index, true, cb)
}
cb()
}
Glob.prototype._processSimple = function (prefix, index, cb) {
// XXX review this. Shouldn't it be doing the mounting etc
// before doing stat? kinda weird?
var self = this
this._stat(prefix, function (er, exists) {
self._processSimple2(prefix, index, er, exists, cb)
})
}
Glob.prototype._processSimple2 = function (prefix, index, er, exists, cb) {
//console.error('ps2', prefix, exists)
if (!this.matches[index])
this.matches[index] = Object.create(null)
// If it doesn't exist, then just mark the lack of results
if (!exists)
return cb()
if (prefix && isAbsolute(prefix) && !this.nomount) {
var trail = /[\/\\]$/.test(prefix)
if (prefix.charAt(0) === '/') {
prefix = path.join(this.root, prefix)
} else {
prefix = path.resolve(this.root, prefix)
if (trail)
prefix += '/'
}
}
if (process.platform === 'win32')
prefix = prefix.replace(/\\/g, '/')
// Mark this as a match
this._emitMatch(index, prefix)
cb()
}
// Returns either 'DIR', 'FILE', or false
Glob.prototype._stat = function (f, cb) {
var abs = this._makeAbs(f)
var needDir = f.slice(-1) === '/'
if (f.length > this.maxLength)
return cb()
if (!this.stat && ownProp(this.cache, abs)) {
var c = this.cache[abs]
if (Array.isArray(c))
c = 'DIR'
// It exists, but maybe not how we need it
if (!needDir || c === 'DIR')
return cb(null, c)
if (needDir && c === 'FILE')
return cb()
// otherwise we have to stat, because maybe c=true
// if we know it exists, but not what it is.
}
var exists
var stat = this.statCache[abs]
if (stat !== undefined) {
if (stat === false)
return cb(null, stat)
else {
var type = stat.isDirectory() ? 'DIR' : 'FILE'
if (needDir && type === 'FILE')
return cb()
else
return cb(null, type, stat)
}
}
var self = this
var statcb = inflight('stat\0' + abs, lstatcb_)
if (statcb)
fs.lstat(abs, statcb)
function lstatcb_ (er, lstat) {
if (lstat && lstat.isSymbolicLink()) {
// If it's a symlink, then treat it as the target, unless
// the target does not exist, then treat it as a file.
return fs.stat(abs, function (er, stat) {
if (er)
self._stat2(f, abs, null, lstat, cb)
else
self._stat2(f, abs, er, stat, cb)
})
} else {
self._stat2(f, abs, er, lstat, cb)
}
}
}
Glob.prototype._stat2 = function (f, abs, er, stat, cb) {
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
this.statCache[abs] = false
return cb()
}
var needDir = f.slice(-1) === '/'
this.statCache[abs] = stat
if (abs.slice(-1) === '/' && stat && !stat.isDirectory())
return cb(null, false, stat)
var c = true
if (stat)
c = stat.isDirectory() ? 'DIR' : 'FILE'
this.cache[abs] = this.cache[abs] || c
if (needDir && c === 'FILE')
return cb()
return cb(null, c, stat)
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | module.exports = globSync
globSync.GlobSync = GlobSync
var fs = require('fs')
var rp = require('fs.realpath')
var minimatch = require('minimatch')
var Minimatch = minimatch.Minimatch
var Glob = require('./glob.js').Glob
var util = require('util')
var path = require('path')
var assert = require('assert')
var isAbsolute = require('path-is-absolute')
var common = require('./common.js')
var alphasort = common.alphasort
var alphasorti = common.alphasorti
var setopts = common.setopts
var ownProp = common.ownProp
var childrenIgnored = common.childrenIgnored
var isIgnored = common.isIgnored
function globSync (pattern, options) {
if (typeof options === 'function' || arguments.length === 3)
throw new TypeError('callback provided to sync glob\n'+
'See: https://github.com/isaacs/node-glob/issues/167')
return new GlobSync(pattern, options).found
}
function GlobSync (pattern, options) {
if (!pattern)
throw new Error('must provide pattern')
if (typeof options === 'function' || arguments.length === 3)
throw new TypeError('callback provided to sync glob\n'+
'See: https://github.com/isaacs/node-glob/issues/167')
if (!(this instanceof GlobSync))
return new GlobSync(pattern, options)
setopts(this, pattern, options)
if (this.noprocess)
return this
var n = this.minimatch.set.length
this.matches = new Array(n)
for (var i = 0; i < n; i ++) {
this._process(this.minimatch.set[i], i, false)
}
this._finish()
}
GlobSync.prototype._finish = function () {
assert(this instanceof GlobSync)
if (this.realpath) {
var self = this
this.matches.forEach(function (matchset, index) {
var set = self.matches[index] = Object.create(null)
for (var p in matchset) {
try {
p = self._makeAbs(p)
var real = rp.realpathSync(p, self.realpathCache)
set[real] = true
} catch (er) {
if (er.syscall === 'stat')
set[self._makeAbs(p)] = true
else
throw er
}
}
})
}
common.finish(this)
}
GlobSync.prototype._process = function (pattern, index, inGlobStar) {
assert(this instanceof GlobSync)
// Get the first [n] parts of pattern that are all strings.
var n = 0
while (typeof pattern[n] === 'string') {
n ++
}
// now n is the index of the first one that is *not* a string.
// See if there's anything else
var prefix
switch (n) {
// if not, then this is rather simple
case pattern.length:
this._processSimple(pattern.join('/'), index)
return
case 0:
// pattern *starts* with some non-trivial item.
// going to readdir(cwd), but not include the prefix in matches.
prefix = null
break
default:
// pattern has some string bits in the front.
// whatever it starts with, whether that's 'absolute' like /foo/bar,
// or 'relative' like '../baz'
prefix = pattern.slice(0, n).join('/')
break
}
var remain = pattern.slice(n)
// get the list of entries.
var read
if (prefix === null)
read = '.'
else if (isAbsolute(prefix) || isAbsolute(pattern.join('/'))) {
if (!prefix || !isAbsolute(prefix))
prefix = '/' + prefix
read = prefix
} else
read = prefix
var abs = this._makeAbs(read)
//if ignored, skip processing
if (childrenIgnored(this, read))
return
var isGlobStar = remain[0] === minimatch.GLOBSTAR
if (isGlobStar)
this._processGlobStar(prefix, read, abs, remain, index, inGlobStar)
else
this._processReaddir(prefix, read, abs, remain, index, inGlobStar)
}
GlobSync.prototype._processReaddir = function (prefix, read, abs, remain, index, inGlobStar) {
var entries = this._readdir(abs, inGlobStar)
// if the abs isn't a dir, then nothing can match!
if (!entries)
return
// It will only match dot entries if it starts with a dot, or if
// dot is set. Stuff like @(.foo|.bar) isn't allowed.
var pn = remain[0]
var negate = !!this.minimatch.negate
var rawGlob = pn._glob
var dotOk = this.dot || rawGlob.charAt(0) === '.'
var matchedEntries = []
for (var i = 0; i < entries.length; i++) {
var e = entries[i]
if (e.charAt(0) !== '.' || dotOk) {
var m
if (negate && !prefix) {
m = !e.match(pn)
} else {
m = e.match(pn)
}
if (m)
matchedEntries.push(e)
}
}
var len = matchedEntries.length
// If there are no matched entries, then nothing matches.
if (len === 0)
return
// if this is the last remaining pattern bit, then no need for
// an additional stat *unless* the user has specified mark or
// stat explicitly. We know they exist, since readdir returned
// them.
if (remain.length === 1 && !this.mark && !this.stat) {
if (!this.matches[index])
this.matches[index] = Object.create(null)
for (var i = 0; i < len; i ++) {
var e = matchedEntries[i]
if (prefix) {
if (prefix.slice(-1) !== '/')
e = prefix + '/' + e
else
e = prefix + e
}
if (e.charAt(0) === '/' && !this.nomount) {
e = path.join(this.root, e)
}
this._emitMatch(index, e)
}
// This was the last one, and no stats were needed
return
}
// now test all matched entries as stand-ins for that part
// of the pattern.
remain.shift()
for (var i = 0; i < len; i ++) {
var e = matchedEntries[i]
var newPattern
if (prefix)
newPattern = [prefix, e]
else
newPattern = [e]
this._process(newPattern.concat(remain), index, inGlobStar)
}
}
GlobSync.prototype._emitMatch = function (index, e) {
if (isIgnored(this, e))
return
var abs = this._makeAbs(e)
if (this.mark)
e = this._mark(e)
if (this.absolute) {
e = abs
}
if (this.matches[index][e])
return
if (this.nodir) {
var c = this.cache[abs]
if (c === 'DIR' || Array.isArray(c))
return
}
this.matches[index][e] = true
if (this.stat)
this._stat(e)
}
GlobSync.prototype._readdirInGlobStar = function (abs) {
// follow all symlinked directories forever
// just proceed as if this is a non-globstar situation
if (this.follow)
return this._readdir(abs, false)
var entries
var lstat
var stat
try {
lstat = fs.lstatSync(abs)
} catch (er) {
if (er.code === 'ENOENT') {
// lstat failed, doesn't exist
return null
}
}
var isSym = lstat && lstat.isSymbolicLink()
this.symlinks[abs] = isSym
// If it's not a symlink or a dir, then it's definitely a regular file.
// don't bother doing a readdir in that case.
if (!isSym && lstat && !lstat.isDirectory())
this.cache[abs] = 'FILE'
else
entries = this._readdir(abs, false)
return entries
}
GlobSync.prototype._readdir = function (abs, inGlobStar) {
var entries
if (inGlobStar && !ownProp(this.symlinks, abs))
return this._readdirInGlobStar(abs)
if (ownProp(this.cache, abs)) {
var c = this.cache[abs]
if (!c || c === 'FILE')
return null
if (Array.isArray(c))
return c
}
try {
return this._readdirEntries(abs, fs.readdirSync(abs))
} catch (er) {
this._readdirError(abs, er)
return null
}
}
GlobSync.prototype._readdirEntries = function (abs, entries) {
// if we haven't asked to stat everything, then just
// assume that everything in there exists, so we can avoid
// having to stat it a second time.
if (!this.mark && !this.stat) {
for (var i = 0; i < entries.length; i ++) {
var e = entries[i]
if (abs === '/')
e = abs + e
else
e = abs + '/' + e
this.cache[e] = true
}
}
this.cache[abs] = entries
// mark and cache dir-ness
return entries
}
GlobSync.prototype._readdirError = function (f, er) {
// handle errors, and cache the information
switch (er.code) {
case 'ENOTSUP': // https://github.com/isaacs/node-glob/issues/205
case 'ENOTDIR': // totally normal. means it *does* exist.
var abs = this._makeAbs(f)
this.cache[abs] = 'FILE'
if (abs === this.cwdAbs) {
var error = new Error(er.code + ' invalid cwd ' + this.cwd)
error.path = this.cwd
error.code = er.code
throw error
}
break
case 'ENOENT': // not terribly unusual
case 'ELOOP':
case 'ENAMETOOLONG':
case 'UNKNOWN':
this.cache[this._makeAbs(f)] = false
break
default: // some unusual error. Treat as failure.
this.cache[this._makeAbs(f)] = false
if (this.strict)
throw er
if (!this.silent)
console.error('glob error', er)
break
}
}
GlobSync.prototype._processGlobStar = function (prefix, read, abs, remain, index, inGlobStar) {
var entries = this._readdir(abs, inGlobStar)
// no entries means not a dir, so it can never have matches
// foo.txt/** doesn't match foo.txt
if (!entries)
return
// test without the globstar, and with every child both below
// and replacing the globstar.
var remainWithoutGlobStar = remain.slice(1)
var gspref = prefix ? [ prefix ] : []
var noGlobStar = gspref.concat(remainWithoutGlobStar)
// the noGlobStar pattern exits the inGlobStar state
this._process(noGlobStar, index, false)
var len = entries.length
var isSym = this.symlinks[abs]
// If it's a symlink, and we're in a globstar, then stop
if (isSym && inGlobStar)
return
for (var i = 0; i < len; i++) {
var e = entries[i]
if (e.charAt(0) === '.' && !this.dot)
continue
// these two cases enter the inGlobStar state
var instead = gspref.concat(entries[i], remainWithoutGlobStar)
this._process(instead, index, true)
var below = gspref.concat(entries[i], remain)
this._process(below, index, true)
}
}
GlobSync.prototype._processSimple = function (prefix, index) {
// XXX review this. Shouldn't it be doing the mounting etc
// before doing stat? kinda weird?
var exists = this._stat(prefix)
if (!this.matches[index])
this.matches[index] = Object.create(null)
// If it doesn't exist, then just mark the lack of results
if (!exists)
return
if (prefix && isAbsolute(prefix) && !this.nomount) {
var trail = /[\/\\]$/.test(prefix)
if (prefix.charAt(0) === '/') {
prefix = path.join(this.root, prefix)
} else {
prefix = path.resolve(this.root, prefix)
if (trail)
prefix += '/'
}
}
if (process.platform === 'win32')
prefix = prefix.replace(/\\/g, '/')
// Mark this as a match
this._emitMatch(index, prefix)
}
// Returns either 'DIR', 'FILE', or false
GlobSync.prototype._stat = function (f) {
var abs = this._makeAbs(f)
var needDir = f.slice(-1) === '/'
if (f.length > this.maxLength)
return false
if (!this.stat && ownProp(this.cache, abs)) {
var c = this.cache[abs]
if (Array.isArray(c))
c = 'DIR'
// It exists, but maybe not how we need it
if (!needDir || c === 'DIR')
return c
if (needDir && c === 'FILE')
return false
// otherwise we have to stat, because maybe c=true
// if we know it exists, but not what it is.
}
var exists
var stat = this.statCache[abs]
if (!stat) {
var lstat
try {
lstat = fs.lstatSync(abs)
} catch (er) {
if (er && (er.code === 'ENOENT' || er.code === 'ENOTDIR')) {
this.statCache[abs] = false
return false
}
}
if (lstat && lstat.isSymbolicLink()) {
try {
stat = fs.statSync(abs)
} catch (er) {
stat = lstat
}
} else {
stat = lstat
}
}
this.statCache[abs] = stat
var c = true
if (stat)
c = stat.isDirectory() ? 'DIR' : 'FILE'
this.cache[abs] = this.cache[abs] || c
if (needDir && c === 'FILE')
return false
return c
}
GlobSync.prototype._mark = function (p) {
return common.mark(this, p)
}
GlobSync.prototype._makeAbs = function (f) {
return common.makeAbs(this, f)
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| fs.js | 81.82% | (9 / 11) | 66.67% | (4 / 6) | 100% | (2 / 2) | 81.82% | (9 / 11) | |
| graceful-fs.js | 41.72% | (68 / 163) | 9.88% | (8 / 81) | 14.71% | (5 / 34) | 41.72% | (68 / 163) | |
| legacy-streams.js | 6.85% | (5 / 73) | 0% | (0 / 32) | 0% | (0 / 5) | 7.14% | (5 / 70) | |
| polyfills.js | 36.59% | (75 / 205) | 17.65% | (21 / 119) | 23.4% | (11 / 47) | 39.43% | (69 / 175) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 1 1 1 1 1 1 1 82 1 | 'use strict'
var fs = require('fs')
module.exports = clone(fs)
function clone (obj) {
Iif (obj === null || typeof obj !== 'object')
return obj
Eif (obj instanceof Object)
var copy = { __proto__: obj.__proto__ }
else
var copy = Object.create(null)
Object.getOwnPropertyNames(obj).forEach(function (key) {
Object.defineProperty(copy, key, Object.getOwnPropertyDescriptor(obj, key))
})
return copy
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 121 121 121 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 121 121 | var fs = require('fs')
var polyfills = require('./polyfills.js')
var legacy = require('./legacy-streams.js')
var queue = []
var util = require('util')
function noop () {}
var debug = noop
Eif (util.debuglog)
debug = util.debuglog('gfs4')
else if (/\bgfs4\b/i.test(process.env.NODE_DEBUG || ''))
debug = function() {
var m = util.format.apply(util, arguments)
m = 'GFS4: ' + m.split(/\n/).join('\nGFS4: ')
console.error(m)
}
Iif (/\bgfs4\b/i.test(process.env.NODE_DEBUG || '')) {
process.on('exit', function() {
debug(queue)
require('assert').equal(queue.length, 0)
})
}
module.exports = patch(require('./fs.js'))
Iif (process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH) {
module.exports = patch(fs)
}
// Always patch fs.close/closeSync, because we want to
// retry() whenever a close happens *anywhere* in the program.
// This is essential when multiple graceful-fs instances are
// in play at the same time.
module.exports.close =
fs.close = (function (fs$close) { return function (fd, cb) {
return fs$close.call(fs, fd, function (err) {
if (!err)
retry()
if (typeof cb === 'function')
cb.apply(this, arguments)
})
}})(fs.close)
module.exports.closeSync =
fs.closeSync = (function (fs$closeSync) { return function (fd) {
// Note that graceful-fs also retries when fs.closeSync() fails.
// Looks like a bug to me, although it's probably a harmless one.
var rval = fs$closeSync.apply(fs, arguments)
retry()
return rval
}})(fs.closeSync)
function patch (fs) {
// Everything that references the open() function needs to be in here
polyfills(fs)
fs.gracefulify = patch
fs.FileReadStream = ReadStream; // Legacy name.
fs.FileWriteStream = WriteStream; // Legacy name.
fs.createReadStream = createReadStream
fs.createWriteStream = createWriteStream
var fs$readFile = fs.readFile
fs.readFile = readFile
function readFile (path, options, cb) {
if (typeof options === 'function')
cb = options, options = null
return go$readFile(path, options, cb)
function go$readFile (path, options, cb) {
return fs$readFile(path, options, function (err) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$readFile, [path, options, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
var fs$writeFile = fs.writeFile
fs.writeFile = writeFile
function writeFile (path, data, options, cb) {
if (typeof options === 'function')
cb = options, options = null
return go$writeFile(path, data, options, cb)
function go$writeFile (path, data, options, cb) {
return fs$writeFile(path, data, options, function (err) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$writeFile, [path, data, options, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
var fs$appendFile = fs.appendFile
Eif (fs$appendFile)
fs.appendFile = appendFile
function appendFile (path, data, options, cb) {
if (typeof options === 'function')
cb = options, options = null
return go$appendFile(path, data, options, cb)
function go$appendFile (path, data, options, cb) {
return fs$appendFile(path, data, options, function (err) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$appendFile, [path, data, options, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
var fs$readdir = fs.readdir
fs.readdir = readdir
function readdir (path, options, cb) {
var args = [path]
if (typeof options !== 'function') {
args.push(options)
} else {
cb = options
}
args.push(go$readdir$cb)
return go$readdir(args)
function go$readdir$cb (err, files) {
if (files && files.sort)
files.sort()
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$readdir, [args]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
}
}
function go$readdir (args) {
return fs$readdir.apply(fs, args)
}
Iif (process.version.substr(0, 4) === 'v0.8') {
var legStreams = legacy(fs)
ReadStream = legStreams.ReadStream
WriteStream = legStreams.WriteStream
}
var fs$ReadStream = fs.ReadStream
ReadStream.prototype = Object.create(fs$ReadStream.prototype)
ReadStream.prototype.open = ReadStream$open
var fs$WriteStream = fs.WriteStream
WriteStream.prototype = Object.create(fs$WriteStream.prototype)
WriteStream.prototype.open = WriteStream$open
fs.ReadStream = ReadStream
fs.WriteStream = WriteStream
function ReadStream (path, options) {
if (this instanceof ReadStream)
return fs$ReadStream.apply(this, arguments), this
else
return ReadStream.apply(Object.create(ReadStream.prototype), arguments)
}
function ReadStream$open () {
var that = this
open(that.path, that.flags, that.mode, function (err, fd) {
if (err) {
if (that.autoClose)
that.destroy()
that.emit('error', err)
} else {
that.fd = fd
that.emit('open', fd)
that.read()
}
})
}
function WriteStream (path, options) {
if (this instanceof WriteStream)
return fs$WriteStream.apply(this, arguments), this
else
return WriteStream.apply(Object.create(WriteStream.prototype), arguments)
}
function WriteStream$open () {
var that = this
open(that.path, that.flags, that.mode, function (err, fd) {
if (err) {
that.destroy()
that.emit('error', err)
} else {
that.fd = fd
that.emit('open', fd)
}
})
}
function createReadStream (path, options) {
return new ReadStream(path, options)
}
function createWriteStream (path, options) {
return new WriteStream(path, options)
}
var fs$open = fs.open
fs.open = open
function open (path, flags, mode, cb) {
if (typeof mode === 'function')
cb = mode, mode = null
return go$open(path, flags, mode, cb)
function go$open (path, flags, mode, cb) {
return fs$open(path, flags, mode, function (err, fd) {
if (err && (err.code === 'EMFILE' || err.code === 'ENFILE'))
enqueue([go$open, [path, flags, mode, cb]])
else {
if (typeof cb === 'function')
cb.apply(this, arguments)
retry()
}
})
}
}
return fs
}
function enqueue (elem) {
debug('ENQUEUE', elem[0].name, elem[1])
queue.push(elem)
}
function retry () {
var elem = queue.shift()
Iif (elem) {
debug('RETRY', elem[0].name, elem[1])
elem[0].apply(null, elem[1])
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | 1 1 1 1 1 | var Stream = require('stream').Stream
module.exports = legacy
function legacy (fs) {
return {
ReadStream: ReadStream,
WriteStream: WriteStream
}
function ReadStream (path, options) {
if (!(this instanceof ReadStream)) return new ReadStream(path, options);
Stream.call(this);
var self = this;
this.path = path;
this.fd = null;
this.readable = true;
this.paused = false;
this.flags = 'r';
this.mode = 438; /*=0666*/
this.bufferSize = 64 * 1024;
options = options || {};
// Mixin options into this
var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}
if (this.encoding) this.setEncoding(this.encoding);
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.end === undefined) {
this.end = Infinity;
} else if ('number' !== typeof this.end) {
throw TypeError('end must be a Number');
}
if (this.start > this.end) {
throw new Error('start must be <= end');
}
this.pos = this.start;
}
if (this.fd !== null) {
process.nextTick(function() {
self._read();
});
return;
}
fs.open(this.path, this.flags, this.mode, function (err, fd) {
if (err) {
self.emit('error', err);
self.readable = false;
return;
}
self.fd = fd;
self.emit('open', fd);
self._read();
})
}
function WriteStream (path, options) {
if (!(this instanceof WriteStream)) return new WriteStream(path, options);
Stream.call(this);
this.path = path;
this.fd = null;
this.writable = true;
this.flags = 'w';
this.encoding = 'binary';
this.mode = 438; /*=0666*/
this.bytesWritten = 0;
options = options || {};
// Mixin options into this
var keys = Object.keys(options);
for (var index = 0, length = keys.length; index < length; index++) {
var key = keys[index];
this[key] = options[key];
}
if (this.start !== undefined) {
if ('number' !== typeof this.start) {
throw TypeError('start must be a Number');
}
if (this.start < 0) {
throw new Error('start must be >= zero');
}
this.pos = this.start;
}
this.busy = false;
this._queue = [];
if (this.fd === null) {
this._open = fs.open;
this._queue.push([this._open, this.path, this.flags, this.mode, undefined]);
this.flush();
}
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | 1 1 1 1 1 1 170 1 170 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 2 1 3 2 1 3 2 1 3 2 1 3 3 1 3 3 1 | var fs = require('./fs.js')
var constants = require('constants')
var origCwd = process.cwd
var cwd = null
var platform = process.env.GRACEFUL_FS_PLATFORM || process.platform
process.cwd = function() {
if (!cwd)
cwd = origCwd.call(process)
return cwd
}
try {
process.cwd()
} catch (er) {}
var chdir = process.chdir
process.chdir = function(d) {
cwd = null
chdir.call(process, d)
}
module.exports = patch
function patch (fs) {
// (re-)implement some things that are known busted or missing.
// lchmod, broken prior to 0.6.2
// back-port the fix here.
Iif (constants.hasOwnProperty('O_SYMLINK') &&
process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)) {
patchLchmod(fs)
}
// lutimes implementation, or no-op
Eif (!fs.lutimes) {
patchLutimes(fs)
}
// https://github.com/isaacs/node-graceful-fs/issues/4
// Chown should not fail on einval or eperm if non-root.
// It should not fail on enosys ever, as this just indicates
// that a fs doesn't support the intended operation.
fs.chown = chownFix(fs.chown)
fs.fchown = chownFix(fs.fchown)
fs.lchown = chownFix(fs.lchown)
fs.chmod = chmodFix(fs.chmod)
fs.fchmod = chmodFix(fs.fchmod)
fs.lchmod = chmodFix(fs.lchmod)
fs.chownSync = chownFixSync(fs.chownSync)
fs.fchownSync = chownFixSync(fs.fchownSync)
fs.lchownSync = chownFixSync(fs.lchownSync)
fs.chmodSync = chmodFixSync(fs.chmodSync)
fs.fchmodSync = chmodFixSync(fs.fchmodSync)
fs.lchmodSync = chmodFixSync(fs.lchmodSync)
fs.stat = statFix(fs.stat)
fs.fstat = statFix(fs.fstat)
fs.lstat = statFix(fs.lstat)
fs.statSync = statFixSync(fs.statSync)
fs.fstatSync = statFixSync(fs.fstatSync)
fs.lstatSync = statFixSync(fs.lstatSync)
// if lchmod/lchown do not exist, then make them no-ops
Eif (!fs.lchmod) {
fs.lchmod = function (path, mode, cb) {
if (cb) process.nextTick(cb)
}
fs.lchmodSync = function () {}
}
Eif (!fs.lchown) {
fs.lchown = function (path, uid, gid, cb) {
if (cb) process.nextTick(cb)
}
fs.lchownSync = function () {}
}
// on Windows, A/V software can lock the directory, causing this
// to fail with an EACCES or EPERM if the directory contains newly
// created files. Try again on failure, for up to 60 seconds.
// Set the timeout this long because some Windows Anti-Virus, such as Parity
// bit9, may lock files for up to a minute, causing npm package install
// failures. Also, take care to yield the scheduler. Windows scheduling gives
// CPU to a busy looping process, which can cause the program causing the lock
// contention to be starved of CPU by node, so the contention doesn't resolve.
Iif (platform === "win32") {
fs.rename = (function (fs$rename) { return function (from, to, cb) {
var start = Date.now()
var backoff = 0;
fs$rename(from, to, function CB (er) {
if (er
&& (er.code === "EACCES" || er.code === "EPERM")
&& Date.now() - start < 60000) {
setTimeout(function() {
fs.stat(to, function (stater, st) {
if (stater && stater.code === "ENOENT")
fs$rename(from, to, CB);
else
cb(er)
})
}, backoff)
if (backoff < 100)
backoff += 10;
return;
}
if (cb) cb(er)
})
}})(fs.rename)
}
// if read() returns EAGAIN, then just try it again.
fs.read = (function (fs$read) { return function (fd, buffer, offset, length, position, callback_) {
var callback
if (callback_ && typeof callback_ === 'function') {
var eagCounter = 0
callback = function (er, _, __) {
if (er && er.code === 'EAGAIN' && eagCounter < 10) {
eagCounter ++
return fs$read.call(fs, fd, buffer, offset, length, position, callback)
}
callback_.apply(this, arguments)
}
}
return fs$read.call(fs, fd, buffer, offset, length, position, callback)
}})(fs.read)
fs.readSync = (function (fs$readSync) { return function (fd, buffer, offset, length, position) {
var eagCounter = 0
while (true) {
try {
return fs$readSync.call(fs, fd, buffer, offset, length, position)
} catch (er) {
if (er.code === 'EAGAIN' && eagCounter < 10) {
eagCounter ++
continue
}
throw er
}
}
}})(fs.readSync)
}
function patchLchmod (fs) {
fs.lchmod = function (path, mode, callback) {
fs.open( path
, constants.O_WRONLY | constants.O_SYMLINK
, mode
, function (err, fd) {
if (err) {
if (callback) callback(err)
return
}
// prefer to return the chmod error, if one occurs,
// but still try to close, and report closing errors if they occur.
fs.fchmod(fd, mode, function (err) {
fs.close(fd, function(err2) {
if (callback) callback(err || err2)
})
})
})
}
fs.lchmodSync = function (path, mode) {
var fd = fs.openSync(path, constants.O_WRONLY | constants.O_SYMLINK, mode)
// prefer to return the chmod error, if one occurs,
// but still try to close, and report closing errors if they occur.
var threw = true
var ret
try {
ret = fs.fchmodSync(fd, mode)
threw = false
} finally {
if (threw) {
try {
fs.closeSync(fd)
} catch (er) {}
} else {
fs.closeSync(fd)
}
}
return ret
}
}
function patchLutimes (fs) {
Iif (constants.hasOwnProperty("O_SYMLINK")) {
fs.lutimes = function (path, at, mt, cb) {
fs.open(path, constants.O_SYMLINK, function (er, fd) {
if (er) {
if (cb) cb(er)
return
}
fs.futimes(fd, at, mt, function (er) {
fs.close(fd, function (er2) {
if (cb) cb(er || er2)
})
})
})
}
fs.lutimesSync = function (path, at, mt) {
var fd = fs.openSync(path, constants.O_SYMLINK)
var ret
var threw = true
try {
ret = fs.futimesSync(fd, at, mt)
threw = false
} finally {
if (threw) {
try {
fs.closeSync(fd)
} catch (er) {}
} else {
fs.closeSync(fd)
}
}
return ret
}
} else {
fs.lutimes = function (_a, _b, _c, cb) { if (cb) process.nextTick(cb) }
fs.lutimesSync = function () {}
}
}
function chmodFix (orig) {
if (!orig) return orig
return function (target, mode, cb) {
return orig.call(fs, target, mode, function (er) {
if (chownErOk(er)) er = null
if (cb) cb.apply(this, arguments)
})
}
}
function chmodFixSync (orig) {
if (!orig) return orig
return function (target, mode) {
try {
return orig.call(fs, target, mode)
} catch (er) {
if (!chownErOk(er)) throw er
}
}
}
function chownFix (orig) {
if (!orig) return orig
return function (target, uid, gid, cb) {
return orig.call(fs, target, uid, gid, function (er) {
if (chownErOk(er)) er = null
if (cb) cb.apply(this, arguments)
})
}
}
function chownFixSync (orig) {
if (!orig) return orig
return function (target, uid, gid) {
try {
return orig.call(fs, target, uid, gid)
} catch (er) {
if (!chownErOk(er)) throw er
}
}
}
function statFix (orig) {
Iif (!orig) return orig
// Older versions of Node erroneously returned signed integers for
// uid + gid.
return function (target, cb) {
return orig.call(fs, target, function (er, stats) {
if (!stats) return cb.apply(this, arguments)
if (stats.uid < 0) stats.uid += 0x100000000
if (stats.gid < 0) stats.gid += 0x100000000
if (cb) cb.apply(this, arguments)
})
}
}
function statFixSync (orig) {
Iif (!orig) return orig
// Older versions of Node erroneously returned signed integers for
// uid + gid.
return function (target) {
var stats = orig.call(fs, target)
if (stats.uid < 0) stats.uid += 0x100000000
if (stats.gid < 0) stats.gid += 0x100000000
return stats;
}
}
// ENOSYS means that the fs doesn't support the op. Just ignore
// that, because it doesn't matter.
//
// if there's no getuid, or if getuid() is something other
// than 0, and the error is EINVAL or EPERM, then just ignore
// it.
//
// This specific case is a silent failure in cp, install, tar,
// and most other unix tools that manage permissions.
//
// When running as root, or if other types of errors are
// encountered, then it's strict.
function chownErOk (er) {
if (!er)
return true
if (er.code === "ENOSYS")
return true
var nonroot = !process.getuid || process.getuid() !== 0
if (nonroot) {
if (er.code === "EINVAL" || er.code === "EPERM")
return true
}
return false
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 100% | (6 / 6) | 50% | (4 / 8) | 100% | (1 / 1) | 100% | (6 / 6) |
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 11 11 11 11 11 | 'use strict';
module.exports = function (flag, argv) {
argv = argv || process.argv;
var terminatorPos = argv.indexOf('--');
var prefix = /^--/.test(flag) ? '' : '--';
var pos = argv.indexOf(prefix + flag);
return pos !== -1 && (terminatorPos !== -1 ? pos < terminatorPos : true);
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| git-host-info.js | 100% | (9 / 9) | 100% | (2 / 2) | 100% | (3 / 3) | 100% | (8 / 8) | |
| git-host.js | 26.76% | (19 / 71) | 3.57% | (1 / 28) | 0% | (0 / 20) | 27.54% | (19 / 69) | |
| index.js | 15.38% | (10 / 65) | 0% | (0 / 49) | 0% | (0 / 7) | 18.87% | (10 / 53) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 1 1 1 4 36 25 4 19 | 'use strict'
var gitHosts = module.exports = {
github: {
// First two are insecure and generally shouldn't be used any more, but
// they are still supported.
'protocols': [ 'git', 'http', 'git+ssh', 'git+https', 'ssh', 'https' ],
'domain': 'github.com',
'treepath': 'tree',
'filetemplate': 'https://{auth@}raw.githubusercontent.com/{user}/{project}/{committish}/{path}',
'bugstemplate': 'https://{domain}/{user}/{project}/issues',
'gittemplate': 'git://{auth@}{domain}/{user}/{project}.git{#committish}',
'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz'
},
bitbucket: {
'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ],
'domain': 'bitbucket.org',
'treepath': 'src',
'tarballtemplate': 'https://{domain}/{user}/{project}/get/{committish}.tar.gz'
},
gitlab: {
'protocols': [ 'git+ssh', 'git+https', 'ssh', 'https' ],
'domain': 'gitlab.com',
'treepath': 'tree',
'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#README',
'bugstemplate': 'https://{domain}/{user}/{project}/issues',
'tarballtemplate': 'https://{domain}/{user}/{project}/repository/archive.tar.gz?ref={committish}'
},
gist: {
'protocols': [ 'git', 'git+ssh', 'git+https', 'ssh', 'https' ],
'domain': 'gist.github.com',
'pathmatch': /^[/](?:([^/]+)[/])?([a-z0-9]+)(?:[.]git)?$/,
'filetemplate': 'https://gist.githubusercontent.com/{user}/{project}/raw{/committish}/{path}',
'bugstemplate': 'https://{domain}/{project}',
'gittemplate': 'git://{domain}/{project}.git{#committish}',
'sshtemplate': 'git@{domain}:/{project}.git{#committish}',
'sshurltemplate': 'git+ssh://git@{domain}/{project}.git{#committish}',
'browsetemplate': 'https://{domain}/{project}{/committish}',
'docstemplate': 'https://{domain}/{project}{/committish}',
'httpstemplate': 'git+https://{domain}/{project}.git{#committish}',
'shortcuttemplate': '{type}:{project}{#committish}',
'pathtemplate': '{project}{#committish}',
'tarballtemplate': 'https://{domain}/{user}/{project}/archive/{committish}.tar.gz'
}
}
var gitHostDefaults = {
'sshtemplate': 'git@{domain}:{user}/{project}.git{#committish}',
'sshurltemplate': 'git+ssh://git@{domain}/{user}/{project}.git{#committish}',
'browsetemplate': 'https://{domain}/{user}/{project}{/tree/committish}',
'docstemplate': 'https://{domain}/{user}/{project}{/tree/committish}#readme',
'httpstemplate': 'git+https://{auth@}{domain}/{user}/{project}.git{#committish}',
'filetemplate': 'https://{domain}/{user}/{project}/raw/{committish}/{path}',
'shortcuttemplate': '{type}:{user}/{project}{#committish}',
'pathtemplate': '{user}/{project}{#committish}',
'pathmatch': /^[/]([^/]+)[/]([^/]+?)(?:[.]git|[/])?$/
}
Object.keys(gitHosts).forEach(function (name) {
Object.keys(gitHostDefaults).forEach(function (key) {
if (gitHosts[name][key]) return
gitHosts[name][key] = gitHostDefaults[key]
})
gitHosts[name].protocols_re = RegExp('^(' +
gitHosts[name].protocols.map(function (protocol) {
return protocol.replace(/([\\+*{}()[\]$^|])/g, '\\$1')
}).join('|') + '):$')
})
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict'
var gitHosts = require('./git-host-info.js')
var extend = Object.assign || require('util')._extend
var GitHost = module.exports = function (type, user, auth, project, committish, defaultRepresentation, opts) {
var gitHostInfo = this
gitHostInfo.type = type
Object.keys(gitHosts[type]).forEach(function (key) {
gitHostInfo[key] = gitHosts[type][key]
})
gitHostInfo.user = user
gitHostInfo.auth = auth
gitHostInfo.project = project
gitHostInfo.committish = committish
gitHostInfo.default = defaultRepresentation
gitHostInfo.opts = opts || {}
}
GitHost.prototype = {}
GitHost.prototype.hash = function () {
return this.committish ? '#' + this.committish : ''
}
GitHost.prototype._fill = function (template, opts) {
if (!template) return
var vars = extend({}, opts)
opts = extend(extend({}, this.opts), opts)
var self = this
Object.keys(this).forEach(function (key) {
if (self[key] != null && vars[key] == null) vars[key] = self[key]
})
var rawAuth = vars.auth
var rawComittish = vars.committish
Object.keys(vars).forEach(function (key) {
vars[key] = encodeURIComponent(vars[key])
})
vars['auth@'] = rawAuth ? rawAuth + '@' : ''
if (opts.noCommittish) {
vars['#committish'] = ''
vars['/tree/committish'] = ''
vars['/comittish'] = ''
vars.comittish = ''
} else {
vars['#committish'] = rawComittish ? '#' + rawComittish : ''
vars['/tree/committish'] = vars.committish
? '/' + vars.treepath + '/' + vars.committish
: ''
vars['/committish'] = vars.committish ? '/' + vars.committish : ''
vars.committish = vars.committish || 'master'
}
var res = template
Object.keys(vars).forEach(function (key) {
res = res.replace(new RegExp('[{]' + key + '[}]', 'g'), vars[key])
})
if (opts.noGitPlus) {
return res.replace(/^git[+]/, '')
} else {
return res
}
}
GitHost.prototype.ssh = function (opts) {
return this._fill(this.sshtemplate, opts)
}
GitHost.prototype.sshurl = function (opts) {
return this._fill(this.sshurltemplate, opts)
}
GitHost.prototype.browse = function (opts) {
return this._fill(this.browsetemplate, opts)
}
GitHost.prototype.docs = function (opts) {
return this._fill(this.docstemplate, opts)
}
GitHost.prototype.bugs = function (opts) {
return this._fill(this.bugstemplate, opts)
}
GitHost.prototype.https = function (opts) {
return this._fill(this.httpstemplate, opts)
}
GitHost.prototype.git = function (opts) {
return this._fill(this.gittemplate, opts)
}
GitHost.prototype.shortcut = function (opts) {
return this._fill(this.shortcuttemplate, opts)
}
GitHost.prototype.path = function (opts) {
return this._fill(this.pathtemplate, opts)
}
GitHost.prototype.tarball = function (opts) {
return this._fill(this.tarballtemplate, opts)
}
GitHost.prototype.file = function (P, opts) {
return this._fill(this.filetemplate, extend({
path: P.replace(/^[/]+/g, '')
}, opts))
}
GitHost.prototype.getDefaultRepresentation = function () {
return this.default
}
GitHost.prototype.toString = function (opts) {
return (this[this.default] || this.sshurl).call(this, opts)
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 1 1 1 1 1 1 1 1 1 1 | 'use strict'
var url = require('url')
var gitHosts = require('./git-host-info.js')
var GitHost = module.exports = require('./git-host.js')
var protocolToRepresentationMap = {
'git+ssh': 'sshurl',
'git+https': 'https',
'ssh': 'sshurl',
'git': 'git'
}
function protocolToRepresentation (protocol) {
if (protocol.substr(-1) === ':') protocol = protocol.slice(0, -1)
return protocolToRepresentationMap[protocol] || protocol
}
var authProtocols = {
'git:': true,
'https:': true,
'git+https:': true,
'http:': true,
'git+http:': true
}
module.exports.fromUrl = function (giturl, opts) {
if (giturl == null || giturl === '') return
var url = fixupUnqualifiedGist(
isGitHubShorthand(giturl) ? 'github:' + giturl : giturl
)
var parsed = parseGitUrl(url)
var shortcutMatch = url.match(new RegExp('^([^:]+):(?:(?:[^@:]+(?:[^@]+)?@)?([^/]*))[/](.+?)(?:[.]git)?($|#)'))
var matches = Object.keys(gitHosts).map(function (gitHostName) {
try {
var gitHostInfo = gitHosts[gitHostName]
var auth = null
if (parsed.auth && authProtocols[parsed.protocol]) {
auth = decodeURIComponent(parsed.auth)
}
var committish = parsed.hash ? decodeURIComponent(parsed.hash.substr(1)) : null
var user = null
var project = null
var defaultRepresentation = null
if (shortcutMatch && shortcutMatch[1] === gitHostName) {
user = shortcutMatch[2] && decodeURIComponent(shortcutMatch[2])
project = decodeURIComponent(shortcutMatch[3])
defaultRepresentation = 'shortcut'
} else {
if (parsed.host !== gitHostInfo.domain) return
if (!gitHostInfo.protocols_re.test(parsed.protocol)) return
if (!parsed.path) return
var pathmatch = gitHostInfo.pathmatch
var matched = parsed.path.match(pathmatch)
if (!matched) return
if (matched[1] != null) user = decodeURIComponent(matched[1])
if (matched[2] != null) project = decodeURIComponent(matched[2])
defaultRepresentation = protocolToRepresentation(parsed.protocol)
}
return new GitHost(gitHostName, user, auth, project, committish, defaultRepresentation, opts)
} catch (ex) {
if (!(ex instanceof URIError)) throw ex
}
}).filter(function (gitHostInfo) { return gitHostInfo })
if (matches.length !== 1) return
return matches[0]
}
function isGitHubShorthand (arg) {
// Note: This does not fully test the git ref format.
// See https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
//
// The only way to do this properly would be to shell out to
// git-check-ref-format, and as this is a fast sync function,
// we don't want to do that. Just let git fail if it turns
// out that the commit-ish is invalid.
// GH usernames cannot start with . or -
return /^[^:@%/\s.-][^:@%/\s]*[/][^:@\s/%]+(?:#.*)?$/.test(arg)
}
function fixupUnqualifiedGist (giturl) {
// necessary for round-tripping gists
var parsed = url.parse(giturl)
if (parsed.protocol === 'gist:' && parsed.host && !parsed.path) {
return parsed.protocol + '/' + parsed.host
} else {
return giturl
}
}
function parseGitUrl (giturl) {
if (typeof giturl !== 'string') giturl = '' + giturl
var matched = giturl.match(/^([^@]+)@([^:/]+):[/]?((?:[^/]+[/])?[^/]+?)(?:[.]git)?(#.*)?$/)
if (!matched) return url.parse(giturl)
return {
protocol: 'git+ssh:',
slashes: true,
auth: matched[1],
host: matched[2],
port: null,
hostname: matched[2],
hash: matched[4],
search: null,
query: null,
pathname: '/' + matched[3],
path: '/' + matched[3],
href: 'git+ssh://' + matched[1] + '@' + matched[2] +
'/' + matched[3] + (matched[4] || '')
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| imurmurhash.js | 23.19% | (16 / 69) | 17.14% | (6 / 35) | 60% | (3 / 5) | 23.19% | (16 / 69) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /**
* @preserve
* JS Implementation of incremental MurmurHash3 (r150) (as of May 10, 2013)
*
* @author <a href="mailto:jensyt@gmail.com">Jens Taylor</a>
* @see http://github.com/homebrewing/brauhaus-diff
* @author <a href="mailto:gary.court@gmail.com">Gary Court</a>
* @see http://github.com/garycourt/murmurhash-js
* @author <a href="mailto:aappleby@gmail.com">Austin Appleby</a>
* @see http://sites.google.com/site/murmurhash/
*/
(function(){
var cache;
// Call this function without `new` to use the cached object (good for
// single-threaded environments), or with `new` to create a new object.
//
// @param {string} key A UTF-16 or ASCII string
// @param {number} seed An optional positive integer
// @return {object} A MurmurHash3 object for incremental hashing
function MurmurHash3(key, seed) {
var m = this instanceof MurmurHash3 ? this : cache;
m.reset(seed)
Iif (typeof key === 'string' && key.length > 0) {
m.hash(key);
}
Iif (m !== this) {
return m;
}
};
// Incrementally add a string to this hash
//
// @param {string} key A UTF-16 or ASCII string
// @return {object} this
MurmurHash3.prototype.hash = function(key) {
var h1, k1, i, top, len;
len = key.length;
this.len += len;
k1 = this.k1;
i = 0;
switch (this.rem) {
case 0: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) : 0;
case 1: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 8 : 0;
case 2: k1 ^= len > i ? (key.charCodeAt(i++) & 0xffff) << 16 : 0;
case 3:
k1 ^= len > i ? (key.charCodeAt(i) & 0xff) << 24 : 0;
k1 ^= len > i ? (key.charCodeAt(i++) & 0xff00) >> 8 : 0;
}
this.rem = (len + this.rem) & 3; // & 3 is same as % 4
len -= this.rem;
if (len > 0) {
h1 = this.h1;
while (1) {
k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff;
h1 ^= k1;
h1 = (h1 << 13) | (h1 >>> 19);
h1 = (h1 * 5 + 0xe6546b64) & 0xffffffff;
if (i >= len) {
break;
}
k1 = ((key.charCodeAt(i++) & 0xffff)) ^
((key.charCodeAt(i++) & 0xffff) << 8) ^
((key.charCodeAt(i++) & 0xffff) << 16);
top = key.charCodeAt(i++);
k1 ^= ((top & 0xff) << 24) ^
((top & 0xff00) >> 8);
}
k1 = 0;
switch (this.rem) {
case 3: k1 ^= (key.charCodeAt(i + 2) & 0xffff) << 16;
case 2: k1 ^= (key.charCodeAt(i + 1) & 0xffff) << 8;
case 1: k1 ^= (key.charCodeAt(i) & 0xffff);
}
this.h1 = h1;
}
this.k1 = k1;
return this;
};
// Get the result of this hash
//
// @return {number} The 32-bit hash
MurmurHash3.prototype.result = function() {
var k1, h1;
k1 = this.k1;
h1 = this.h1;
if (k1 > 0) {
k1 = (k1 * 0x2d51 + (k1 & 0xffff) * 0xcc9e0000) & 0xffffffff;
k1 = (k1 << 15) | (k1 >>> 17);
k1 = (k1 * 0x3593 + (k1 & 0xffff) * 0x1b870000) & 0xffffffff;
h1 ^= k1;
}
h1 ^= this.len;
h1 ^= h1 >>> 16;
h1 = (h1 * 0xca6b + (h1 & 0xffff) * 0x85eb0000) & 0xffffffff;
h1 ^= h1 >>> 13;
h1 = (h1 * 0xae35 + (h1 & 0xffff) * 0xc2b20000) & 0xffffffff;
h1 ^= h1 >>> 16;
return h1 >>> 0;
};
// Reset the hash object for reuse
//
// @param {number} seed An optional positive integer
MurmurHash3.prototype.reset = function(seed) {
this.h1 = typeof seed === 'number' ? seed : 0;
this.rem = this.k1 = this.len = 0;
return this;
};
// A cached object to use. This can be safely used if you're in a single-
// threaded environment, otherwise you need to create new hashes to use.
cache = new MurmurHash3();
Eif (typeof(module) != 'undefined') {
module.exports = MurmurHash3;
} else {
this.MurmurHash3 = MurmurHash3;
}
}());
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| inflight.js | 24.14% | (7 / 29) | 0% | (0 / 4) | 0% | (0 / 5) | 25% | (7 / 28) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 1 1 1 1 1 1 1 | var wrappy = require('wrappy')
var reqs = Object.create(null)
var once = require('once')
module.exports = wrappy(inflight)
function inflight (key, cb) {
if (reqs[key]) {
reqs[key].push(cb)
return null
} else {
reqs[key] = [cb]
return makeres(key)
}
}
function makeres (key) {
return once(function RES () {
var cbs = reqs[key]
var len = cbs.length
var args = slice(arguments)
// XXX It's somewhat ambiguous whether a new callback added in this
// pass should be queued for later execution if something in the
// list of callbacks throws, or if it should just be discarded.
// However, it's such an edge case that it hardly matters, and either
// choice is likely as surprising as the other.
// As it happens, we do go ahead and schedule it for later execution.
try {
for (var i = 0; i < len; i++) {
cbs[i].apply(null, args)
}
} finally {
if (cbs.length > len) {
// added more in the interim.
// de-zalgo, just in case, but don't call again.
cbs.splice(0, len)
process.nextTick(function () {
RES.apply(null, args)
})
} else {
delete reqs[key]
}
}
})
}
function slice (args) {
var length = args.length
var array = []
for (var i = 0; i < length; i++) array[i] = args[i]
return array
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| inherits.js | 66.67% | (4 / 6) | 50% | (1 / 2) | 100% | (0 / 0) | 80% | (4 / 5) |
| 1 2 3 4 5 6 7 8 9 | 1 1 1 1 | try {
var util = require('util');
Iif (typeof util.inherits !== 'function') throw '';
module.exports = util.inherits;
} catch (e) {
module.exports = require('./inherits_browser.js');
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 25% | (1 / 4) | 0% | (0 / 6) | 0% | (0 / 1) | 25% | (1 / 4) |
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 | 'use strict'; module.exports = function isArrayish(obj) { if (!obj) { return false; } return obj instanceof Array || Array.isArray(obj) || (obj.length >= 0 && obj.splice instanceof Function); }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (3 / 6) | 0% | (0 / 10) | 0% | (0 / 3) | 50% | (3 / 6) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 1 1 1 | /*! * Determine if an object is a Buffer * * @author Feross Aboukhadijeh <feross@feross.org> <http://feross.org> * @license MIT */ // The _isBuffer check is for Safari 5-7 support, because it's missing // Object.prototype.constructor. Remove this eventually module.exports = function (obj) { return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) } function isBuffer (obj) { return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) } // For Node v0.10 support. Remove this eventually. function isSlowBuffer (obj) { return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 40% | (2 / 5) | 0% | (0 / 2) | 0% | (0 / 1) | 40% | (2 / 5) |
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 1 | 'use strict';
var builtinModules = require('builtin-modules');
module.exports = function (str) {
if (typeof str !== 'string') {
throw new TypeError('Expected a string');
}
return builtinModules.indexOf(str) !== -1;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 20% | (1 / 5) | 0% | (0 / 6) | 0% | (0 / 1) | 20% | (1 / 5) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 1 | /*! * is-dotfile <https://github.com/regexps/is-dotfile> * * Copyright (c) 2015 Jon Schlinkert, contributors. * Licensed under the MIT license. */ module.exports = function(str) { if (str.charCodeAt(0) === 46 /* . */ && str.indexOf('/', 1) === -1) { return true; } var last = str.lastIndexOf('/'); return last !== -1 ? str.charCodeAt(last + 1) === 46 /* . */ : false; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 14.29% | (2 / 14) | 0% | (0 / 15) | 0% | (0 / 1) | 16.67% | (2 / 12) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 1 1 | /*!
* is-equal-shallow <https://github.com/jonschlinkert/is-equal-shallow>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var isPrimitive = require('is-primitive');
module.exports = function isEqual(a, b) {
if (!a && !b) { return true; }
if (!a && b || a && !b) { return false; }
var numKeysA = 0, numKeysB = 0, key;
for (key in b) {
numKeysB++;
if (!isPrimitive(b[key]) || !a.hasOwnProperty(key) || (a[key] !== b[key])) {
return false;
}
}
for (key in a) {
numKeysA++;
}
return numKeysA === numKeysB;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (1 / 2) | 0% | (0 / 4) | 0% | (0 / 1) | 50% | (1 / 2) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 | /*! * is-extendable <https://github.com/jonschlinkert/is-extendable> * * Copyright (c) 2015, Jon Schlinkert. * Licensed under the MIT License. */ 'use strict'; module.exports = function isExtendable(val) { return typeof val !== 'undefined' && val !== null && (typeof val === 'object' || typeof val === 'function'); }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (1 / 2) | 0% | (0 / 2) | 0% | (0 / 1) | 50% | (1 / 2) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 | 1 | /*! * is-extglob <https://github.com/jonschlinkert/is-extglob> * * Copyright (c) 2014-2015, Jon Schlinkert. * Licensed under the MIT License. */ module.exports = function isExtglob(str) { return typeof str === 'string' && /[@?!+*]\(/.test(str); }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 66.67% | (2 / 3) | 0% | (0 / 3) | 0% | (0 / 1) | 66.67% | (2 / 3) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 1 | /*!
* is-glob <https://github.com/jonschlinkert/is-glob>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
var isExtglob = require('is-extglob');
module.exports = function isGlob(str) {
return typeof str === 'string'
&& (/[*!?{}(|)[\]]/.test(str)
|| isExtglob(str));
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 28.57% | (2 / 7) | 0% | (0 / 6) | 0% | (0 / 1) | 28.57% | (2 / 7) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 1 1 | /*!
* is-number <https://github.com/jonschlinkert/is-number>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var typeOf = require('kind-of');
module.exports = function isNumber(num) {
var type = typeOf(num);
if (type !== 'number' && type !== 'string') {
return false;
}
var n = +num;
return (n - n + 1) >= 0 && num !== '';
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (1 / 2) | 0% | (0 / 2) | 0% | (0 / 1) | 50% | (1 / 2) |
| 1 2 3 4 5 6 7 8 9 10 11 12 | 1 | /*! * is-posix-bracket <https://github.com/jonschlinkert/is-posix-bracket> * * Copyright (c) 2015-2016, Jon Schlinkert. * Licensed under the MIT License. */ module.exports = function isPosixBracket(str) { return typeof str === 'string' && /\[([:.=+])(?:[^\[\]]|)+\1\]/.test(str); }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (1 / 2) | 0% | (0 / 3) | 0% | (0 / 1) | 50% | (1 / 2) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 1 | /*! * is-primitive <https://github.com/jonschlinkert/is-primitive> * * Copyright (c) 2014-2015, Jon Schlinkert. * Licensed under the MIT License. */ 'use strict'; // see http://jsperf.com/testing-value-is-primitive/7 module.exports = function isPrimitive(value) { return value == null || (typeof value !== 'function' && typeof value !== 'object'); }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| is-utf8.js | 5.88% | (1 / 17) | 0% | (0 / 57) | 0% | (0 / 1) | 5.88% | (1 / 17) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | 1 | exports = module.exports = function(bytes) { var i = 0; while(i < bytes.length) { if( (// ASCII bytes[i] == 0x09 || bytes[i] == 0x0A || bytes[i] == 0x0D || (0x20 <= bytes[i] && bytes[i] <= 0x7E) ) ) { i += 1; continue; } if( (// non-overlong 2-byte (0xC2 <= bytes[i] && bytes[i] <= 0xDF) && (0x80 <= bytes[i+1] && bytes[i+1] <= 0xBF) ) ) { i += 2; continue; } if( (// excluding overlongs bytes[i] == 0xE0 && (0xA0 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) ) || (// straight 3-byte ((0xE1 <= bytes[i] && bytes[i] <= 0xEC) || bytes[i] == 0xEE || bytes[i] == 0xEF) && (0x80 <= bytes[i + 1] && bytes[i+1] <= 0xBF) && (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) ) || (// excluding surrogates bytes[i] == 0xED && (0x80 <= bytes[i+1] && bytes[i+1] <= 0x9F) && (0x80 <= bytes[i+2] && bytes[i+2] <= 0xBF) ) ) { i += 3; continue; } if( (// planes 1-3 bytes[i] == 0xF0 && (0x90 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) ) || (// planes 4-15 (0xF1 <= bytes[i] && bytes[i] <= 0xF3) && (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0xBF) && (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) ) || (// plane 16 bytes[i] == 0xF4 && (0x80 <= bytes[i + 1] && bytes[i + 1] <= 0x8F) && (0x80 <= bytes[i + 2] && bytes[i + 2] <= 0xBF) && (0x80 <= bytes[i + 3] && bytes[i + 3] <= 0xBF) ) ) { i += 4; continue; } return false; } return true; } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 66.67% | (2 / 3) | 50% | (1 / 2) | 0% | (0 / 1) | 66.67% | (2 / 3) |
| 1 2 3 4 5 6 7 | 1 1 | var toString = {}.toString;
module.exports = Array.isArray || function (arr) {
return toString.call(arr) == '[object Array]';
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 66.67% | (2 / 3) | 0% | (0 / 3) | 0% | (0 / 1) | 66.67% | (2 / 3) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 1 1 | /*!
* isobject <https://github.com/jonschlinkert/isobject>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var isArray = require('isarray');
module.exports = function isObject(val) {
return val != null && typeof val === 'object' && isArray(val) === false;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 25% | (3 / 12) | 0% | (0 / 12) | 0% | (0 / 3) | 25% | (3 / 12) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
/**
* istanbul-lib-coverage exports an API that allows you to create and manipulate
* file coverage, coverage maps (a set of file coverage objects) and summary
* coverage objects. File coverage for the same file can be merged as can
* entire coverage maps.
*
* @module Exports
*/
var CoverageSummary = require('./lib/file').CoverageSummary,
FileCoverage = require('./lib/file').FileCoverage,
CoverageMap = require('./lib/coverage-map').CoverageMap;
module.exports = {
/**
* creates a coverage summary object
* @param {Object} obj an argument with the same semantics
* as the one passed to the `CoverageSummary` constructor
* @returns {CoverageSummary}
*/
createCoverageSummary: function (obj) {
if (obj && obj instanceof CoverageSummary) {
return obj;
}
return new CoverageSummary(obj);
},
/**
* creates a CoverageMap object
* @param {Object} obj optional - an argument with the same semantics
* as the one passed to the CoverageMap constructor.
* @returns {CoverageMap}
*/
createCoverageMap: function (obj) {
if (obj && obj instanceof CoverageMap) {
return obj;
}
return new CoverageMap(obj);
},
/**
* creates a FileCoverage object
* @param {Object} obj optional - an argument with the same semantics
* as the one passed to the FileCoverage constructor.
* @returns {FileCoverage}
*/
createFileCoverage: function (obj) {
if (obj && obj instanceof FileCoverage) {
return obj;
}
return new FileCoverage(obj);
}
};
/** classes exported for reuse */
module.exports.classes = {
/**
* the file coverage constructor
*/
FileCoverage: FileCoverage
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| coverage-map.js | 22.22% | (10 / 45) | 0% | (0 / 14) | 0% | (0 / 11) | 22.22% | (10 / 45) | |
| file.js | 16.91% | (23 / 136) | 0% | (0 / 49) | 5.13% | (2 / 39) | 17.04% | (23 / 135) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 1 1 1 1 1 1 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var FileCoverage = require('./file').FileCoverage,
CoverageSummary = require('./file').CoverageSummary;
function loadMap(source) {
var data = {};
Object.keys(source).forEach(function (k) {
var cov = source[k];
if (cov instanceof FileCoverage) {
data[k] = cov;
} else {
data[k] = new FileCoverage(cov);
}
});
return data;
}
/**
* CoverageMap is a map of `FileCoverage` objects keyed by file paths.
* @param {Object} [obj=undefined] obj A coverage map from which to initialize this
* map's contents. This can be the raw global coverage object.
* @constructor
*/
function CoverageMap(obj) {
if (!obj) {
this.data = {};
} else if (obj instanceof CoverageMap) {
this.data = obj.data;
} else {
this.data = loadMap(obj);
}
}
/**
* merges a second coverage map into this one
* @param {CoverageMap} obj - a CoverageMap or its raw data. Coverage is merged
* correctly for the same files and additional file coverage keys are created
* as needed.
*/
CoverageMap.prototype.merge = function (obj) {
var that = this,
other;
if (obj instanceof CoverageMap) {
other = obj;
} else {
other = new CoverageMap(obj);
}
Object.keys(other.data).forEach(function (k) {
var fc = other.data[k];
if (that.data[k]) {
that.data[k].merge(fc);
} else {
that.data[k] = fc;
}
});
};
/**
* returns a JSON-serializable POJO for this coverage map
* @returns {Object}
*/
CoverageMap.prototype.toJSON = function () {
return this.data;
};
/**
* returns an array for file paths for which this map has coverage
* @returns {Array{string}} - array of files
*/
CoverageMap.prototype.files = function () {
return Object.keys(this.data);
};
/**
* returns the file coverage for the specified file.
* @param {String} file
* @returns {FileCoverage}
*/
CoverageMap.prototype.fileCoverageFor = function (file) {
var fc = this.data[file];
if (!fc) {
throw new Error('No file coverage available for: ' + file);
}
return fc;
};
/**
* adds a file coverage object to this map. If the path for the object,
* already exists in the map, it is merged with the existing coverage
* otherwise a new key is added to the map.
* @param {FileCoverage} fc the file coverage to add
*/
CoverageMap.prototype.addFileCoverage = function (fc) {
var cov = new FileCoverage(fc),
path = cov.path;
if (this.data[path]) {
this.data[path].merge(cov);
} else {
this.data[path] = cov;
}
};
/**
* returns the coverage summary for all the file coverage objects in this map.
* @returns {CoverageSummary}
*/
CoverageMap.prototype.getCoverageSummary = function () {
var that = this,
ret = new CoverageSummary();
this.files().forEach(function (key) {
ret.merge(that.fileCoverageFor(key).toSummary());
});
return ret;
};
module.exports = {
CoverageMap: CoverageMap
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | 1 1 1 1 1 4 1 1 1 1 1 1 1 1 1 7 1 1 1 1 1 1 1 | /* Copyright 2012-2015, Yahoo Inc. Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. */ "use strict"; function percent(covered, total) { var tmp; if (total > 0) { tmp = 1000 * 100 * covered / total + 5; return Math.floor(tmp / 10) / 100; } else { return 100.00; } } function blankSummary() { var empty = function () { return { total: 0, covered: 0, skipped: 0, pct: 'Unknown' }; }; return { lines: empty(), statements: empty(), functions: empty(), branches: empty() }; } // asserts that a data object "looks like" a summary coverage object function assertValidSummary(obj) { var valid = obj && obj.lines && obj.statements && obj.functions && obj.branches; if (!valid) { throw new Error('Invalid summary coverage object, missing keys, found:' + Object.keys(obj).join(',')); } } /** * CoverageSummary provides a summary of code coverage . It exposes 4 properties, * `lines`, `statements`, `branches`, and `functions`. Each of these properties * is an object that has 4 keys `total`, `covered`, `skipped` and `pct`. * `pct` is a percentage number (0-100). * @param {Object|CoverageSummary} [obj=undefined] an optional data object or * another coverage summary to initialize this object with. * @constructor */ function CoverageSummary(obj) { if (!obj) { this.data = blankSummary(); } else if (obj instanceof CoverageSummary) { this.data = obj.data; } else { this.data = obj; } assertValidSummary(this.data); } ['lines', 'statements', 'functions', 'branches'].forEach(function (p) { Object.defineProperty(CoverageSummary.prototype, p, { enumerable: true, get: function () { return this.data[p]; } }); }); /** * merges a second summary coverage object into this one * @param {CoverageSummary} obj - another coverage summary object */ CoverageSummary.prototype.merge = function (obj) { var that = this, keys = ['lines', 'statements', 'branches', 'functions']; keys.forEach(function (key) { that[key].total += obj[key].total; that[key].covered += obj[key].covered; that[key].skipped += obj[key].skipped; that[key].pct = percent(that[key].covered, that[key].total); }); return this; }; /** * returns a POJO that is JSON serializable. May be used to get the raw * summary object. */ CoverageSummary.prototype.toJSON = function () { return this.data; }; // returns a data object that represents empty coverage function emptyCoverage(filePath) { return { path: filePath, statementMap: {}, fnMap: {}, branchMap: {}, s: {}, f: {}, b: {} }; } // asserts that a data object "looks like" a coverage object function assertValidObject(obj) { var valid = obj && obj.path && obj.statementMap && obj.fnMap && obj.branchMap && obj.s && obj.f && obj.b; if (!valid) { throw new Error('Invalid file coverage object, missing keys, found:' + Object.keys(obj).join(',')); } } /** * provides a read-only view of coverage for a single file. * The deep structure of this object is documented elsewhere. It has the following * properties: * * * `path` - the file path for which coverage is being tracked * * `statementMap` - map of statement locations keyed by statement index * * `functionMap` - map of function metadata keyed by function index * * `branchMap` - map of branch metadata keyed by branch index * * `s` - hit counts for statements * * `f` - hit count for functions * * `b` - hit count for branches * * @param {Object|FileCoverage|String} pathOrObj is a string that initializes * and empty coverage object with the specified file path or a data object that * has all the required properties for a file coverage object. * @constructor */ function FileCoverage(pathOrObj) { if (!pathOrObj) { throw new Error("Coverage must be initialized with a path or an object"); } if (typeof pathOrObj === 'string') { this.data = emptyCoverage(pathOrObj); } else if (pathOrObj instanceof FileCoverage) { this.data = pathOrObj.data; } else if (typeof pathOrObj === 'object') { this.data = pathOrObj; } else { throw new Error('Invalid argument to coverage constructor'); } assertValidObject(this.data); } /** * returns computed line coverage from statement coverage. * This is a map of hits keyed by line number in the source. */ FileCoverage.prototype.getLineCoverage = function () { var statementMap = this.data.statementMap, statements = this.data.s, lineMap = {}; Object.keys(statements).forEach(function (st) { if (!statementMap[st]) { return; } var line = statementMap[st].start.line, count = statements[st], prevVal = lineMap[line]; if (prevVal === undefined || prevVal < count) { lineMap[line] = count; } }); return lineMap; }; /** * returns an array of uncovered line numbers. * @returns {Array} an array of line numbers for which no hits have been * collected. */ FileCoverage.prototype.getUncoveredLines = function () { var lc = this.getLineCoverage(), ret = []; Object.keys(lc).forEach(function (l) { var hits = lc[l]; if (hits === 0) { ret.push(l); } }); return ret; }; /** * returns a map of branch coverage by source line number. * @returns {Object} an object keyed by line number. Each object * has a `covered`, `total` and `coverage` (percentage) property. */ FileCoverage.prototype.getBranchCoverageByLine = function () { var branchMap = this.branchMap, branches = this.b, ret = {}; Object.keys(branchMap).forEach(function (k) { var line = branchMap[k].line, branchData = branches[k]; ret[line] = ret[line] || []; ret[line].push.apply(ret[line], branchData); }); Object.keys(ret).forEach(function (k) { var dataArray = ret[k], covered = dataArray.filter(function (item) { return item > 0; }), coverage = covered.length / dataArray.length * 100; ret[k] = { covered: covered.length, total: dataArray.length, coverage: coverage }; }); return ret; }; // expose coverage data attributes ['path', 'statementMap', 'fnMap', 'branchMap', 's', 'f', 'b' ].forEach(function (p) { Object.defineProperty(FileCoverage.prototype, p, { enumerable: true, get: function () { return this.data[p]; } }); }); /** * return a JSON-serializable POJO for this file coverage object */ FileCoverage.prototype.toJSON = function () { return this.data; }; /** * merges a second coverage object into this one, updating hit counts * @param {FileCoverage} other - the coverage object to be merged into this one. * Note that the other object should have the same structure as this one (same file). */ FileCoverage.prototype.merge = function (other) { var that = this; Object.keys(other.s).forEach(function (k) { that.data.s[k] += other.s[k]; }); Object.keys(other.f).forEach(function (k) { that.data.f[k] += other.f[k]; }); Object.keys(other.b).forEach(function (k) { var i, retArray = that.data.b[k], secondArray = other.b[k]; if (!retArray) { that.data.b[k] = secondArray; return; } for (i = 0; i < retArray.length; i += 1) { retArray[i] += secondArray[i]; } }); }; FileCoverage.prototype.computeSimpleTotals = function (property) { var stats = this[property], ret = {total: 0, covered: 0, skipped: 0}; if (typeof stats === 'function') { stats = stats.call(this); } Object.keys(stats).forEach(function (key) { var covered = !!stats[key]; ret.total += 1; if (covered) { ret.covered += 1; } }); ret.pct = percent(ret.covered, ret.total); return ret; }; FileCoverage.prototype.computeBranchTotals = function () { var stats = this.b, ret = {total: 0, covered: 0, skipped: 0}; Object.keys(stats).forEach(function (key) { var branches = stats[key], covered; branches.forEach(function (branchHits) { covered = branchHits > 0; if (covered) { ret.covered += 1; } }); ret.total += branches.length; }); ret.pct = percent(ret.covered, ret.total); return ret; }; /** * resets hit counts for all statements, functions and branches * in this coverage object resulting in zero coverage. */ FileCoverage.prototype.resetHits = function () { var statements = this.s, functions = this.f, branches = this.b; Object.keys(statements).forEach(function (s) { statements[s] = 0; }); Object.keys(functions).forEach(function (f) { functions[f] = 0; }); Object.keys(branches).forEach(function (b) { var hits = branches[b]; branches[b] = hits.map(function () { return 0; }); }); }; /** * returns a CoverageSummary for this file coverage object * @returns {CoverageSummary} */ FileCoverage.prototype.toSummary = function () { var ret = {}; ret.lines = this.computeSimpleTotals('getLineCoverage'); ret.functions = this.computeSimpleTotals('f', 'fnMap'); ret.statements = this.computeSimpleTotals('s', 'statementMap'); ret.branches = this.computeBranchTotals(); return new CoverageSummary(ret); }; module.exports = { CoverageSummary: CoverageSummary, FileCoverage: FileCoverage }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 100% | (1 / 1) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (1 / 1) |
| 1 2 3 4 5 6 7 | 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
module.exports = require('./lib/hook');
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| hook.js | 16.98% | (9 / 53) | 2.94% | (1 / 34) | 0% | (0 / 14) | 16.98% | (9 / 53) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | 1 1 1 1 1 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var path = require('path'),
vm = require('vm'),
appendTransform = require('append-transform'),
originalCreateScript = vm.createScript,
originalRunInThisContext = vm.runInThisContext;
function transformFn(matcher, transformer, verbose) {
return function (code, filename) {
var shouldHook = typeof filename === 'string' && matcher(path.resolve(filename)),
transformed,
changed = false;
if (shouldHook) {
if (verbose) {
console.error('Module load hook: transform [' + filename + ']');
}
try {
transformed = transformer(code, filename);
changed = true;
} catch (ex) {
console.error('Transformation error for', filename, '; return original code');
console.error(ex.message || String(ex));
if (verbose) {
console.error(ex.stack);
}
transformed = code;
}
} else {
transformed = code;
}
return { code: transformed, changed: changed };
};
}
/**
* unloads the required caches, removing all files that would have matched
* the supplied matcher.
* @param {Function} matcher - the match function that accepts a file name and
* returns if that file should be unloaded from the cache.
*/
function unloadRequireCache(matcher) {
/* istanbul ignore else: impossible to test */
if (matcher && typeof require !== 'undefined' && require && require.cache) {
Object.keys(require.cache).forEach(function (filename) {
if (matcher(filename)) {
delete require.cache[filename];
}
});
}
}
/**
* hooks `require` to return transformed code to the node module loader.
* Exceptions in the transform result in the original code being used instead.
* @method hookRequire
* @static
* @param matcher {Function(filePath)} a function that is called with the absolute path to the file being
* `require`-d. Should return a truthy value when transformations need to be applied to the code, a falsy value otherwise
* @param transformer {Function(code, filePath)} a function called with the original code and the associated path of the file
* from where the code was loaded. Should return the transformed code.
* @param options {Object} options Optional.
* @param {Boolean} [options.verbose] write a line to standard error every time the transformer is called
* @param {Function} [options.postLoadHook] a function that is called with the name of the file being
* required. This is called after the require is processed irrespective of whether it was transformed.
* @returns {Function} a reset function that can be called to remove the hook
*/
function hookRequire(matcher, transformer, options) {
options = options || {};
var extensions,
disable = false,
fn = transformFn(matcher, transformer, options.verbose),
postLoadHook = options.postLoadHook &&
typeof options.postLoadHook === 'function' ? options.postLoadHook : null;
extensions = options.extensions || ['.js'];
extensions.forEach(function(ext){
appendTransform(function (code, filename) {
if (disable) {
return code;
}
var ret = fn(code, filename);
if (postLoadHook) {
postLoadHook(filename);
}
return ret.code;
}, ext);
});
return function () {
disable = true;
};
}
/**
* hooks `vm.createScript` to return transformed code out of which a `Script` object will be created.
* Exceptions in the transform result in the original code being used instead.
* @method hookCreateScript
* @static
* @param matcher {Function(filePath)} a function that is called with the filename passed to `vm.createScript`
* Should return a truthy value when transformations need to be applied to the code, a falsy value otherwise
* @param transformer {Function(code, filePath)} a function called with the original code and the filename passed to
* `vm.createScript`. Should return the transformed code.
* @param options {Object} options Optional.
* @param {Boolean} [options.verbose] write a line to standard error every time the transformer is called
*/
function hookCreateScript(matcher, transformer, opts) {
opts = opts || {};
var fn = transformFn(matcher, transformer, opts.verbose);
vm.createScript = function (code, file) {
var ret = fn(code, file);
return originalCreateScript(ret.code, file);
};
}
/**
* unhooks vm.createScript, restoring it to its original state.
* @method unhookCreateScript
* @static
*/
function unhookCreateScript() {
vm.createScript = originalCreateScript;
}
/**
* hooks `vm.runInThisContext` to return transformed code.
* @method hookRunInThisContext
* @static
* @param matcher {Function(filePath)} a function that is called with the filename passed to `vm.createScript`
* Should return a truthy value when transformations need to be applied to the code, a falsy value otherwise
* @param transformer {Function(code, filePath)} a function called with the original code and the filename passed to
* `vm.createScript`. Should return the transformed code.
* @param opts {Object} [opts={}] options
* @param {Boolean} [opts.verbose] write a line to standard error every time the transformer is called
*/
function hookRunInThisContext(matcher, transformer, opts) {
opts = opts || {};
var fn = transformFn(matcher, transformer, opts.verbose);
vm.runInThisContext = function (code, file) {
var ret = fn(code, file);
return originalRunInThisContext(ret.code, file);
};
}
/**
* unhooks vm.runInThisContext, restoring it to its original state.
* @method unhookRunInThisContext
* @static
*/
function unhookRunInThisContext() {
vm.runInThisContext = originalRunInThisContext;
}
/**
* istanbul-lib-hook provides mechanisms to transform code in the scope of `require`,
* `vm.createScript`, `vm.runInThisContext` etc.
*
* This mechanism is general and relies on a user-supplied `matcher` function that
* determines when transformations should be performed and a user-supplied `transformer`
* function that performs the actual transform. Instrumenting code for coverage is
* one specific example of useful hooking.
*
* Note that both the `matcher` and `transformer` must execute synchronously.
*
* @module Exports
* @example
* var hook = require('istanbul-lib-hook'),
* myMatcher = function (file) { return file.match(/foo/); },
* myTransformer = function (code, file) {
* return 'console.log("' + file + '");' + code;
* };
*
* hook.hookRequire(myMatcher, myTransformer);
* var foo = require('foo'); //will now print foo's module path to console
*/
module.exports = {
hookRequire: hookRequire,
hookCreateScript: hookCreateScript,
unhookCreateScript: unhookCreateScript,
hookRunInThisContext : hookRunInThisContext,
unhookRunInThisContext : unhookRunInThisContext,
unloadRequireCache: unloadRequireCache
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 60% | (3 / 5) | 100% | (0 / 0) | 0% | (0 / 2) | 60% | (3 / 5) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
/**
* @module Exports
*/
var summarizer = require('./lib/summarizer'),
context = require('./lib/context'),
watermarks = require('./lib/watermarks');
module.exports = {
/**
* returns a reporting context for the supplied options
* @param {Object} [opts=null] opts
* @returns {Context}
*/
createContext: function (opts) {
return context.create(opts);
},
/**
* returns the default watermarks that would be used when not
* overridden
* @returns {Object} an object with `statements`, `functions`, `branches`,
* and `line` keys. Each value is a 2 element array that has the low and
* high watermark as percentages.
*/
getDefaultWatermarks: function () {
return watermarks.getDefault();
}
};
/**
* standard summary functions
*/
module.exports.summarizers = {
/**
* a summarizer that creates a flat tree with one root node and bunch of
* files directly under it
*/
flat: summarizer.createFlatSummary,
/**
* a summarizer that creates a hierarchical tree where the coverage summaries
* of each directly reflect the summaries of all subdirectories and files in it
*/
nested: summarizer.createNestedSummary,
/**
* a summarizer that creates a tree in which directories are not nested.
* Every subdirectory is a child of the root node and only reflects the
* coverage numbers for the files in it (i.e. excludes subdirectories).
* This is the default summarizer.
*/
pkg: summarizer.createPackageSummary
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| context.js | 26.83% | (11 / 41) | 0% | (0 / 21) | 0% | (0 / 11) | 26.83% | (11 / 41) | |
| file-writer.js | 46% | (23 / 50) | 33.33% | (6 / 18) | 18.75% | (3 / 16) | 46% | (23 / 50) | |
| path.js | 21.52% | (17 / 79) | 5% | (2 / 40) | 6.25% | (1 / 16) | 21.52% | (17 / 79) | |
| summarizer.js | 16.31% | (23 / 141) | 3.85% | (2 / 52) | 0% | (0 / 34) | 16.43% | (23 / 140) | |
| tree.js | 56.9% | (33 / 58) | 0% | (0 / 14) | 47.83% | (11 / 23) | 56.9% | (33 / 58) | |
| watermarks.js | 50% | (1 / 2) | 100% | (0 / 0) | 0% | (0 / 1) | 50% | (1 / 2) | |
| xml-writer.js | 23.68% | (9 / 38) | 0% | (0 / 10) | 0% | (0 / 10) | 24.32% | (9 / 37) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | 1 1 1 1 1 1 1 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var FileWriter = require('./file-writer'),
XMLWriter = require('./xml-writer'),
tree = require('./tree'),
watermarks = require('./watermarks'),
fs = require('fs');
function defaultSourceLookup(path) {
try {
return fs.readFileSync(path, 'utf8');
} catch (ex) {
throw new Error('Unable to lookup source: ' + path + '(' + ex.message + ')');
}
}
function mergeWatermarks(specified, defaults) {
specified = specified || {};
Object.keys(defaults).forEach(function (k) {
var specValue = specified[k];
if (!(specValue && Array.isArray(specValue) && specValue.length === 2)) {
specified[k] = defaults[k];
}
});
return specified;
}
/**
* A reporting context that is passed to report implementations
* @param {Object} [opts=null] opts options
* @param {String} [opts.dir='coverage'] opts.dir the reporting directory
* @param {Object} [opts.watermarks=null] opts.watermarks watermarks for
* statements, lines, branches and functions
* @param {Function} [opts.sourceFinder=fsLookup] opts.sourceFinder a
* function that returns source code given a file path. Defaults to
* filesystem lookups based on path.
* @constructor
*/
function Context(opts) {
opts = opts || {};
this.dir = opts.dir || 'coverage';
this.watermarks = mergeWatermarks(opts.watermarks, watermarks.getDefault());
this.sourceFinder = opts.sourceFinder || defaultSourceLookup;
this.data = {};
}
Object.defineProperty(Context.prototype, 'writer', {
enumerable: true,
get: function () {
if (!this.data.writer) {
this.data.writer = new FileWriter(this.dir);
}
return this.data.writer;
}
});
/**
* returns a FileWriter implementation for reporting use. Also available
* as the `writer` property on the context.
* @returns {Writer}
*/
Context.prototype.getWriter = function () {
return this.writer;
};
/**
* returns the source code for the specified file path or throws if
* the source could not be found.
* @param {String} filePath the file path as found in a file coverage object
* @returns {String} the source code
*/
Context.prototype.getSource = function (filePath) {
return this.sourceFinder(filePath);
};
/**
* returns the coverage class given a coverage
* types and a percentage value.
* @param {String} type - the coverage type, one of `statements`, `functions`,
* `branches`, or `lines`
* @param {Number} value - the percentage value
* @returns {String} one of `high`, `medium` or `low`
*/
Context.prototype.classForPercent = function (type, value) {
var watermarks = this.watermarks[type];
if (!watermarks) {
return 'unknown';
}
if (value < watermarks[0]) {
return 'low';
}
if (value >= watermarks[1]) {
return 'high';
}
return 'medium';
};
/**
* returns an XML writer for the supplied content writer
* @param {ContentWriter} contentWriter the content writer to which the returned XML writer
* writes data
* @returns {XMLWriter}
*/
Context.prototype.getXMLWriter = function (contentWriter) {
return new XMLWriter(contentWriter);
};
/**
* returns a full visitor given a partial one.
* @param {Object} partialVisitor a partial visitor only having the functions of
* interest to the caller. These functions are called with a scope that is the
* supplied object.
* @returns {Visitor}
*/
Context.prototype.getVisitor = function (partialVisitor) {
return new tree.Visitor(partialVisitor);
};
module.exports = {
create: function (opts) {
return new Context(opts);
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var util = require('util'),
path = require('path'),
fs = require('fs'),
mkdirp = require('mkdirp'),
supportsColor = require('supports-color'),
isAbsolute = path.isAbsolute || /* istanbul ignore next */ function (p) {
return path.resolve(p) === path.normalize(p);
};
/**
* abstract interface for writing content
* @class ContentWriter
* @constructor
*/
/* istanbul ignore next: abstract class */
function ContentWriter() {
}
/**
* writes a string as-is to the destination
* @param {String} str the string to write
*/
/* istanbul ignore next: abstract class */
ContentWriter.prototype.write = function () {
throw new Error('write: must be overridden');
};
/**
* returns the colorized version of a string. Typically,
* content writers that write to files will return the
* same string and ones writing to a tty will wrap it in
* appropriate escape sequences.
* @param {String} str the string to colorize
* @param {String} clazz one of `high`, `medium` or `low`
* @returns {String} the colorized form of the string
*/
ContentWriter.prototype.colorize = function (str /*, clazz*/) {
return str;
};
/**
* writes a string appended with a newline to the destination
* @param {String} str the string to write
*/
ContentWriter.prototype.println = function (str) {
this.write(str + '\n');
};
/**
* closes this content writer. Should be called after all writes are complete.
*/
ContentWriter.prototype.close = function () {
};
/**
* a content writer that writes to a file
* @param {Number} fd - the file descriptor
* @extends ContentWriter
* @constructor
*/
function FileContentWriter(fd) {
this.fd = fd;
}
util.inherits(FileContentWriter, ContentWriter);
FileContentWriter.prototype.write = function (str) {
fs.writeSync(this.fd, str);
};
FileContentWriter.prototype.close = function () {
fs.closeSync(this.fd);
};
/**
* a content writer that writes to the console
* @extends ContentWriter
* @constructor
*/
function ConsoleWriter() {
}
util.inherits(ConsoleWriter, ContentWriter);
ConsoleWriter.prototype.write = function (str) {
process.stdout.write(str);
};
ConsoleWriter.prototype.colorize = function (str, clazz) {
var colors = {
low: '31;1',
medium: '33;1',
high: '32;1'
};
/* istanbul ignore next: different modes for CI and local */
if (supportsColor && colors[clazz]) {
return '\u001b[' + colors[clazz] + 'm' + str + '\u001b[0m';
}
return str;
};
/**
* utility for writing files under a specific directory
* @class FileWriter
* @param {String} baseDir the base directory under which files should be written
* @constructor
*/
function FileWriter(baseDir) {
if (!baseDir) {
throw new Error('baseDir must be specified');
}
mkdirp.sync(baseDir);
this.baseDir = baseDir;
}
/**
* returns a FileWriter that is rooted at the supplied subdirectory
* @param {String} subdir the subdirectory under which to root the
* returned FileWriter
* @returns {FileWriter}
*/
FileWriter.prototype.writerForDir = function (subdir) {
if (isAbsolute(subdir)) {
throw new Error('Cannot create subdir writer for absolute path: ' + subdir);
}
return new FileWriter(this.baseDir + '/' + subdir);
};
/**
* copies a file from a source directory to a destination name
* @param {String} source path to source file
* @param {String} dest relative path to destination file
*/
FileWriter.prototype.copyFile = function (source, dest) {
if (isAbsolute(dest)) {
throw new Error('Cannot write to absolute path: ' + dest);
}
dest = path.resolve(this.baseDir, dest);
mkdirp.sync(path.dirname(dest));
fs.writeFileSync(dest, fs.readFileSync(source));
};
/**
* returns a content writer for writing content to the supplied file.
* @param {String|null} file the relative path to the file or the special
* values `"-"` or `null` for writing to the console
* @returns {ContentWriter}
*/
FileWriter.prototype.writeFile = function (file) {
if (file === null || file === '-') {
return new ConsoleWriter();
}
if (isAbsolute(file)) {
throw new Error('Cannot write to absolute path: ' + file);
}
file = path.resolve(this.baseDir, file);
mkdirp.sync(path.dirname(file));
return new FileContentWriter(fs.openSync(file, 'w'));
};
module.exports = FileWriter;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | 1 1 1 1 1 1 1 1 1 1 1 1 5 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var path = require('path'),
parsePath = require('path-parse'),
SEP = path.sep || /* istanbul ignore next */ '/',
origParser = parsePath,
origSep = SEP;
function makeRelativeNormalizedPath(str, sep) {
var parsed = parsePath(str),
root = parsed.root,
dir,
file = parsed.base,
quoted,
pos;
// handle a weird windows case separately
if (sep === '\\') {
pos = root.indexOf(':\\');
if (pos >= 0) {
root = root.substring(0, pos + 2);
}
}
dir = parsed.dir.substring(root.length);
if (str === '') {
return [];
}
if (sep !== '/') {
quoted = new RegExp(sep.replace(/\W/g, '\\$&'), 'g');
dir = dir.replace(quoted, '/');
file = file.replace(quoted, '/'); // excessively paranoid?
}
if (dir !== '') {
dir = dir + '/' + file;
} else {
dir = file;
}
if (dir.substring(0,1) === '/') {
dir = dir.substring(1);
}
dir = dir.split(/\/+/);
return dir;
}
function Path(strOrArray) {
if (Array.isArray(strOrArray)) {
this.v = strOrArray;
} else if (typeof strOrArray === "string") {
this.v = makeRelativeNormalizedPath(strOrArray, SEP);
} else {
throw new Error('Invalid Path argument must be string or array:' + strOrArray);
}
}
Path.prototype.toString = function () {
return this.v.join('/');
};
Path.prototype.hasParent = function () {
return this.v.length > 0;
};
Path.prototype.parent = function () {
if (!this.hasParent()) {
throw new Error('Unable to get parent for 0 elem path');
}
var p = this.v.slice();
p.pop();
return new Path(p);
};
Path.prototype.elements = function () {
return this.v.slice();
};
Path.prototype.contains = function (other) {
var i;
if (other.length > this.length) {
return false;
}
for (i = 0; i < other.length; i += 1) {
if (this.v[i] !== other.v[i]) {
return false;
}
}
return true;
};
Path.prototype.ancestorOf = function (other) {
return other.contains(this) && other.length !== this.length;
};
Path.prototype.descendantOf = function (other) {
return this.contains(other) && other.length !== this.length;
};
Path.prototype.commonPrefixPath = function (other) {
var len = this.length > other.length ? other.length : this.length,
i,
ret = [];
for (i = 0; i < len; i +=1 ) {
if (this.v[i] === other.v[i]) {
ret.push(this.v[i]);
} else {
break;
}
}
return new Path(ret);
};
['push', 'pop', 'shift', 'unshift', 'splice'].forEach(function (f) {
Path.prototype[f] = function () {
var args = Array.prototype.slice.call(arguments),
v = this.v;
return v[f].apply(v, args);
};
});
Path.compare = function (a, b) {
var al = a.length,
bl = b.length,
astr,
bstr;
if (al < bl) {
return -1;
}
if (al > bl) {
return 1;
}
astr = a.toString();
bstr = b.toString();
return astr < bstr ? -1 : astr > bstr ? 1 : 0;
};
Object.defineProperty(Path.prototype, 'length', {
enumerable: true,
get: function () {
return this.v.length;
}
});
module.exports = Path;
Path.tester = {
setParserAndSep: function (p, sep) {
parsePath = p;
SEP = sep;
},
reset: function () {
parsePath = origParser;
SEP = origSep;
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var Path = require('./path'),
util = require('util'),
tree = require('./tree'),
coverage = require('istanbul-lib-coverage'),
BaseNode = tree.Node,
BaseTree = tree.Tree;
function ReportNode(path, fileCoverage) {
this.path = path;
this.parent = null;
this.fileCoverage = fileCoverage;
this.children = [];
}
util.inherits(ReportNode, BaseNode);
ReportNode.prototype.addChild = function (child) {
child.parent = this;
this.children.push(child);
};
ReportNode.prototype.asRelative = function (p) {
/* istanbul ignore if */
if (p.substring(0,1) === '/') {
return p.substring(1);
}
return p;
};
ReportNode.prototype.getQualifiedName = function () {
return this.asRelative(this.path.toString());
};
ReportNode.prototype.getRelativeName = function () {
var parent = this.getParent(),
myPath = this.path,
relPath,
i,
parentPath = parent ? parent.path : new Path([]);
if (parentPath.ancestorOf(myPath)) {
relPath = new Path(myPath.elements());
for (i = 0; i < parentPath.length; i += 1) {
relPath.shift();
}
return this.asRelative(relPath.toString());
}
return this.asRelative(this.path.toString());
};
ReportNode.prototype.getParent = function () {
return this.parent;
};
ReportNode.prototype.getChildren = function () {
return this.children;
};
ReportNode.prototype.isSummary = function () {
return !this.fileCoverage;
};
ReportNode.prototype.getFileCoverage = function () {
return this.fileCoverage;
};
ReportNode.prototype.getCoverageSummary = function (filesOnly) {
var cacheProp = 'c_' + (filesOnly ? 'files' : 'full'),
summary;
if (this.hasOwnProperty(cacheProp)) {
return this[cacheProp];
}
if (!this.isSummary()) {
summary = this.getFileCoverage().toSummary();
} else {
var count = 0;
summary = coverage.createCoverageSummary();
this.getChildren().forEach(function (child) {
if (filesOnly && child.isSummary()) {
return;
}
count += 1;
summary.merge(child.getCoverageSummary(filesOnly));
});
if (count === 0 && filesOnly) {
summary = null;
}
}
this[cacheProp] = summary;
return summary;
};
function treeFor(root, childPrefix) {
var tree = new BaseTree(),
visitor,
maybePrefix = function (node) {
if (childPrefix && !node.isRoot()) {
node.path.unshift(childPrefix);
}
};
tree.getRoot = function () {
return root;
};
visitor = {
onDetail: function (node) {
maybePrefix(node);
},
onSummary: function (node) {
maybePrefix(node);
node.children.sort(function (a, b) {
var astr = a.path.toString(),
bstr = b.path.toString();
return astr < bstr ? -1 : astr > bstr ? 1: /* istanbul ignore next */ 0;
});
}
};
tree.visit(visitor);
return tree;
}
function findCommonParent(paths) {
if (paths.length === 0) {
return new Path([]);
}
var common = paths[0],
i;
for (i = 1; i < paths.length; i += 1) {
common = common.commonPrefixPath(paths[i]);
if (common.length === 0) {
break;
}
}
return common;
}
function toInitialList(coverageMap) {
var ret = [],
commonParent;
coverageMap.files().forEach(function (filePath) {
var p = new Path(filePath),
coverage = coverageMap.fileCoverageFor(filePath);
ret.push({
filePath: filePath,
path: p,
fileCoverage: coverage
});
});
commonParent = findCommonParent(ret.map(function (o) { return o.path.parent(); }));
if (commonParent.length > 0) {
ret.forEach(function (o) {
o.path.splice(0, commonParent.length);
});
}
return {
list: ret,
commonParent: commonParent
};
}
function toDirParents(list) {
var nodeMap = {},
parentNodeList = [];
list.forEach(function (o) {
var node = new ReportNode(o.path, o.fileCoverage),
parentPath = o.path.parent(),
parent = nodeMap[parentPath.toString()];
if (!parent) {
parent = new ReportNode(parentPath);
nodeMap[parentPath.toString()] = parent;
parentNodeList.push(parent);
}
parent.addChild(node);
});
return parentNodeList;
}
function foldIntoParents(nodeList) {
var ret = [], i, j;
// sort by longest length first
nodeList.sort(function (a, b) {
return -1 * Path.compare(a.path , b.path);
});
for (i = 0; i < nodeList.length; i += 1) {
var first = nodeList[i],
inserted = false;
for (j = i + 1; j < nodeList.length; j += 1) {
var second = nodeList[j];
if (second.path.ancestorOf(first.path)) {
second.addChild(first);
inserted = true;
break;
}
}
if (!inserted) {
ret.push(first);
}
}
return ret;
}
function createRoot() {
return new ReportNode(new Path([]));
}
function createNestedSummary(coverageMap) {
var flattened = toInitialList(coverageMap),
dirParents = toDirParents(flattened.list),
topNodes = foldIntoParents(dirParents),
root;
if (topNodes.length === 0) {
return treeFor(new ReportNode([]));
}
if (topNodes.length === 1) {
return treeFor(topNodes[0]);
}
root = createRoot();
topNodes.forEach(function (node) {
root.addChild(node);
});
return treeFor(root);
}
function createPackageSummary(coverageMap) {
var flattened = toInitialList(coverageMap),
dirParents = toDirParents(flattened.list),
common = flattened.commonParent,
prefix,
root;
if (dirParents.length === 1) {
root = dirParents[0];
} else {
root = createRoot();
// if one of the dirs is itself the root,
// then we need to create a top-level dir
dirParents.forEach(function (dp) {
if (dp.path.length === 0) {
prefix = 'root';
}
});
if (prefix && common.length > 0) {
prefix = common.elements()[common.elements().length - 1];
}
dirParents.forEach(function (node) {
root.addChild(node);
});
}
return treeFor(root, prefix);
}
function createFlatSummary(coverageMap) {
var flattened = toInitialList(coverageMap),
list = flattened.list,
root;
root = createRoot();
list.forEach(function (o) {
var node = new ReportNode(o.path, o.fileCoverage);
root.addChild(node);
});
return treeFor(root);
}
module.exports = {
createNestedSummary: createNestedSummary,
createPackageSummary: createPackageSummary,
createFlatSummary: createFlatSummary
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | 1 1 1 5 5 1 1 1 5 5 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var util = require('util');
/**
* An object with methods that are called during the traversal of the coverage tree.
* A visitor has the following methods that are called during tree traversal.
*
* * `onStart(root, state)` - called before traversal begins
* * `onSummary(node, state)` - called for every summary node
* * `onDetail(node, state)` - called for every detail node
* * `onSummaryEnd(node, state)` - called after all children have been visited for
* a summary node.
* * `onEnd(root, state)` - called after traversal ends
*
* @param delegate - a partial visitor that only implements the methods of interest
* The visitor object supplies the missing methods as noops. For example, reports
* that only need the final coverage summary need implement `onStart` and nothing
* else. Reports that use only detailed coverage information need implement `onDetail`
* and nothing else.
* @constructor
*/
function Visitor(delegate) {
this.delegate = delegate;
}
['Start', 'End', 'Summary', 'SummaryEnd', 'Detail' ].forEach(function (k) {
var f = 'on' + k;
Visitor.prototype[f] = function (node, state) {
if (this.delegate[f] && typeof this.delegate[f] === 'function') {
this.delegate[f].call(this.delegate, node, state);
}
};
});
function CompositeVisitor(visitors) {
if (!Array.isArray(visitors)) {
visitors = [visitors];
}
this.visitors = visitors.map(function (v) {
if (v instanceof Visitor) {
return v;
}
return new Visitor(v);
});
}
util.inherits(CompositeVisitor, Visitor);
['Start', 'Summary', 'SummaryEnd', 'Detail', 'End'].forEach(function (k) {
var f = 'on' + k;
CompositeVisitor.prototype[f] = function (node, state) {
this.visitors.forEach(function (v) {
v[f](node, state);
});
};
});
function Node() {
}
/* istanbul ignore next: abstract method */
Node.prototype.getQualifiedName = function () {
throw new Error('getQualifiedName must be overridden');
};
/* istanbul ignore next: abstract method */
Node.prototype.getRelativeName = function () {
throw new Error('getRelativeName must be overridden');
};
/* istanbul ignore next: abstract method */
Node.prototype.isRoot = function () {
return !this.getParent();
};
/* istanbul ignore next: abstract method */
Node.prototype.getParent = function () {
throw new Error('getParent must be overridden');
};
/* istanbul ignore next: abstract method */
Node.prototype.getChildren = function () {
throw new Error('getChildren must be overridden');
};
/* istanbul ignore next: abstract method */
Node.prototype.isSummary = function () {
throw new Error('isSummary must be overridden');
};
/* istanbul ignore next: abstract method */
Node.prototype.getCoverageSummary = function (/* filesOnly */) {
throw new Error('getCoverageSummary must be overridden');
};
/* istanbul ignore next: abstract method */
Node.prototype.getFileCoverage = function () {
throw new Error('getFileCoverage must be overridden');
};
/**
* visit all nodes depth-first from this node down. Note that `onStart`
* and `onEnd` are never called on the visitor even if the current
* node is the root of the tree.
* @param visitor a full visitor that is called during tree traversal
* @param state optional state that is passed around
*/
Node.prototype.visit = function (visitor, state) {
var that = this,
visitChildren = function () {
that.getChildren().forEach(function (child) {
child.visit(visitor, state);
});
};
if (this.isSummary()) {
visitor.onSummary(this, state);
} else {
visitor.onDetail(this, state);
}
visitChildren();
if (this.isSummary()) {
visitor.onSummaryEnd(this, state);
}
};
/**
* abstract base class for a coverage tree.
* @constructor
*/
function Tree() {
}
/**
* returns the root node of the tree
*/
/* istanbul ignore next: abstract method */
Tree.prototype.getRoot = function () {
throw new Error('getRoot must be overridden');
};
/**
* visits the tree depth-first with the supplied partial visitor
* @param visitor - a potentially partial visitor
* @param state - the state to be passed around during tree traversal
*/
Tree.prototype.visit = function (visitor, state) {
if (!(visitor instanceof Visitor)) {
visitor = new Visitor(visitor);
}
visitor.onStart(this.getRoot(), state);
this.getRoot().visit(visitor, state);
visitor.onEnd(this.getRoot(), state);
};
module.exports = {
Tree: Tree,
Node: Node,
Visitor: Visitor,
CompositeVisitor: CompositeVisitor
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
module.exports = {
getDefault: function () {
return {
statements: [50, 80],
functions: [50, 80],
branches: [50, 80],
lines: [50, 80]
};
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 1 1 1 1 1 1 1 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var INDENT = ' ';
/**
* a utility class to produce well-formed, indented XML
* @param {ContentWriter} contentWriter the content writer that this utility wraps
* @constructor
*/
function XMLWriter(contentWriter) {
this.cw = contentWriter;
this.stack = [];
}
function attrString(attrs) {
if (!attrs) {
return '';
}
var ret = [];
Object.keys(attrs).forEach(function (k) {
var v = attrs[k];
ret.push(k + '="' + v + '"');
});
return ret.length === 0 ? '' : ' ' + ret.join(' ');
}
XMLWriter.prototype.indent = function (str) {
return this.stack.map(function () { return INDENT; }).join('') + str;
};
/**
* writes the opening XML tag with the supplied attributes
* @param {String} name tag name
* @param {Object} [attrs=null] attrs attributes for the tag
*/
XMLWriter.prototype.openTag = function (name, attrs) {
var str = this.indent('<' + name + attrString(attrs) + '>');
this.cw.println(str);
this.stack.push(name);
};
/**
* closes an open XML tag.
* @param {String} name - tag name to close. This must match the writer's
* notion of the tag that is currently open.
*/
XMLWriter.prototype.closeTag = function (name) {
if (this.stack.length === 0) {
throw new Error('Attempt to close tag ' + name + ' when not opened');
}
var stashed = this.stack.pop(),
str = '</' + name + '>';
if (stashed !== name) {
throw new Error('Attempt to close tag ' + name + ' when ' + stashed + ' was the one open');
}
this.cw.println(this.indent(str));
};
/**
* writes a tag and its value opening and closing it at the same time
* @param {String} name tag name
* @param {Object} [attrs=null] attrs tag attributes
* @param {String} [content=null] content optional tag content
*/
XMLWriter.prototype.inlineTag = function (name, attrs, content) {
var str = '<' + name + attrString(attrs);
if (content) {
str += '>' + content + '</' + name + '>';
} else {
str += '/>';
}
str = this.indent(str);
this.cw.println(str);
};
/**
* closes all open tags and ends the document
*/
XMLWriter.prototype.closeAll = function () {
var that = this;
this.stack.slice().reverse().forEach(function (name) {
that.closeTag(name);
});
};
module.exports = XMLWriter;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 44.44% | (16 / 36) | 52% | (26 / 50) | 100% | (2 / 2) | 44.44% | (16 / 36) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var hasFlag = require('has-flag');
var support = function (level) {
Iif (level === 0) {
return false;
}
return {
level: level,
hasBasic: true,
has256: level >= 2,
has16m: level >= 3
};
};
var supportLevel = (function () {
Iif (hasFlag('no-color') ||
hasFlag('no-colors') ||
hasFlag('color=false')) {
return 0;
}
Iif (hasFlag('color=16m') ||
hasFlag('color=full') ||
hasFlag('color=truecolor')) {
return 3;
}
Iif (hasFlag('color=256')) {
return 2;
}
Iif (hasFlag('color') ||
hasFlag('colors') ||
hasFlag('color=true') ||
hasFlag('color=always')) {
return 1;
}
Iif (process.stdout && !process.stdout.isTTY) {
return 0;
}
Iif (process.platform === 'win32') {
return 1;
}
Eif ('CI' in process.env) {
Eif ('TRAVIS' in process.env || process.env.CI === 'Travis') {
return 1;
}
return 0;
}
if ('TEAMCITY_VERSION' in process.env) {
return process.env.TEAMCITY_VERSION.match(/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/) === null ? 0 : 1;
}
if (/^(screen|xterm)-256(?:color)?/.test(process.env.TERM)) {
return 2;
}
if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
return 1;
}
if ('COLORTERM' in process.env) {
return 1;
}
if (process.env.TERM === 'dumb') {
return 0;
}
return 0;
})();
Iif (supportLevel === 0 && 'FORCE_COLOR' in process.env) {
supportLevel = 1;
}
module.exports = process && support(supportLevel);
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 66.67% | (2 / 3) | 100% | (0 / 0) | 0% | (0 / 1) | 66.67% | (2 / 3) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var MapStore = require('./lib/map-store').MapStore;
/**
* @module Exports
*/
module.exports = {
createSourceMapStore: function (opts) {
return new MapStore(opts);
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| map-store.js | 11.48% | (7 / 61) | 0% | (0 / 38) | 0% | (0 / 9) | 11.48% | (7 / 61) | |
| mapped.js | 18% | (9 / 50) | 0% | (0 / 14) | 0% | (0 / 9) | 18% | (9 / 50) | |
| pathutils.js | 44.44% | (4 / 9) | 0% | (0 / 8) | 0% | (0 / 3) | 44.44% | (4 / 9) | |
| source-store.js | 34.88% | (15 / 43) | 0% | (0 / 16) | 0% | (0 / 12) | 34.88% | (15 / 43) | |
| transformer.js | 13.7% | (10 / 73) | 5% | (3 / 60) | 0% | (0 / 11) | 13.7% | (10 / 73) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 1 1 1 1 1 1 1 | /*
Copyright 2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var path = require('path'),
fs = require('fs'),
pathutils = require('./pathutils'),
sourceStore = require('./source-store'),
transformer = require('./transformer'),
SMC = require('source-map').SourceMapConsumer;
/**
* tracks source maps for registered files
* @param {Object} opts [opts=undefined] options.
* @param {Boolean} opts.verbose [opts.verbose=false] verbose mode
* @param {String} opts.baseDir [opts.baseDir=null] alternate base directory
* to resolve sourcemap files
* @param {String} opts.sourceStore [opts.sourceStore='memory'] - store that tracks
* embedded sources found in source maps, one of 'memory' or 'file'
* @param {String} opts.tmpdir [opts.tmpdir=undefined] - temporary directory
* to use for storing files.
* @constructor
*/
function MapStore(opts) {
opts = opts || {};
this.baseDir = opts.baseDir || null;
this.verbose = opts.verbose || false;
this.sourceStore = sourceStore.create(opts.sourceStore, { tmpdir: opts.tmpdir});
this.data = {};
}
/**
* registers a source map URL with this store. It makes some input sanity checks
* and silently fails on malformed input.
* @param transformedFilePath - the file path for which the source map is valid.
* This must *exactly* match the path stashed for the coverage object to be
* useful.
* @param sourceMapUrl - the source map URL, **not** a comment
*/
MapStore.prototype.registerURL = function (transformedFilePath, sourceMapUrl) {
var d = 'data:',
b64 = 'base64,',
pos;
if (sourceMapUrl.length > d.length && sourceMapUrl.substring(0, d.length) === d) {
pos = sourceMapUrl.indexOf(b64);
if (pos > 0) {
this.data[transformedFilePath] = {
type: 'encoded',
data: sourceMapUrl.substring(pos + b64.length)
};
} else {
console.error('Unable to interpret source map URL: ', sourceMapUrl);
}
return;
}
var dir = path.dirname(path.resolve(transformedFilePath)),
file = path.resolve(dir, sourceMapUrl);
this.data[transformedFilePath] = { type: 'file', data: file };
};
/**
* registers a source map object with this store. Makes some basic sanity checks
* and silently fails on malformed input.
* @param transformedFilePath - the file path for which the source map is valid
* @param sourceMap - the source map object
*/
MapStore.prototype.registerMap = function (transformedFilePath, sourceMap) {
if (sourceMap && sourceMap.version) {
this.data[transformedFilePath] = { type: 'object', data: sourceMap };
} else {
console.error('Invalid source map object', sourceMap);
}
};
/**
* transforms the coverage map provided into one that refers to original
* sources when valid mappings have been registered with this store.
* @param {CoverageMap} coverageMap - the coverage map to transform
* @returns {Object} an object with 2 properties. `map` for the transformed
* coverage map and `sourceFinder` which is a function to return the source
* text for a file.
*/
MapStore.prototype.transformCoverage = function (coverageMap) {
var that = this,
mappedCoverage,
sourceFinder;
sourceFinder = function (filePath) {
var content = that.sourceStore.getSource(filePath);
if (content !== null) {
return content;
}
if (pathutils.isAbsolute(filePath)) {
return fs.readFileSync(filePath, 'utf8');
}
return fs.readFileSync(pathutils.asAbsolute(filePath, that.baseDir));
};
coverageMap.files().forEach(function (file) {
var coverage = coverageMap.fileCoverageFor(file);
if (coverage.data.inputSourceMap && !that.data[file]) {
that.registerMap(file, coverage.data.inputSourceMap);
}
});
if (Object.keys(this.data).length === 0) {
return {
map: coverageMap,
sourceFinder: sourceFinder
};
}
mappedCoverage = transformer.create(function (filePath) {
try {
if (!that.data[filePath]) {
return null;
}
var d = that.data[filePath],
obj,
smc;
if (d.type === 'file') {
obj = JSON.parse(fs.readFileSync(d.data, 'utf8'));
} else if (d.type === 'encoded') {
obj = JSON.parse(new Buffer(d.data, 'base64').toString());
} else {
obj = d.data;
}
smc = new SMC(obj);
smc.sources.forEach(function (s) {
var content = smc.sourceContentFor(s),
sourceFilePath = pathutils.relativeTo(s, filePath);
if (content) {
that.sourceStore.registerSource(sourceFilePath, content);
}
});
return smc;
} catch (ex) {
console.error('Error returning source map for ' + filePath);
console.error(ex.message || ex);
if (this.verbose) {
console.error(ex.stack);
}
return null;
}
}).transform(coverageMap);
return {
map: mappedCoverage,
sourceFinder: sourceFinder
};
};
/**
* disposes temporary resources allocated by this map store
*/
MapStore.prototype.dispose = function () {
this.sourceStore.dispose();
};
module.exports = {
MapStore: MapStore
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | 1 1 1 1 1 1 1 1 1 | /*
Copyright 2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var FileCoverage = require('istanbul-lib-coverage').classes.FileCoverage,
util = require('util');
function MappedCoverage(pathOrObj) {
FileCoverage.call(this, pathOrObj);
this.meta = {
last: {
s: 0,
f: 0,
b: 0
},
seen: {}
};
}
util.inherits(MappedCoverage, FileCoverage);
function locString(loc) {
return [loc.start.line, loc.start.column, loc.end.line, loc.end.column].join(':');
}
MappedCoverage.prototype.addStatement = function (loc, hits) {
var key = 's:' + locString(loc),
meta = this.meta,
index = meta.seen[key];
if (index === undefined) {
index = meta.last.s;
meta.last.s += 1;
meta.seen[key] = index;
this.statementMap[index] = this.cloneLocation(loc);
}
this.s[index] = this.s[index] || 0;
this.s[index] += hits;
return index;
};
MappedCoverage.prototype.addFunction = function (name, decl, loc, hits) {
var key = 'f:' + locString(decl),
meta = this.meta,
index = meta.seen[key];
if (index === undefined) {
index = meta.last.f;
meta.last.f += 1;
meta.seen[key] = index;
name = name || '(unknown_' + index + ')';
this.fnMap[index] = {
name: name,
decl: this.cloneLocation(decl),
loc: this.cloneLocation(loc)
};
}
this.f[index] = this.f[index] || 0;
this.f[index] += hits;
return index;
};
MappedCoverage.prototype.addBranch = function (type, loc, branchLocations, hits) {
var key = ['b'],
meta = this.meta,
that = this,
index,
i;
branchLocations.forEach(function (l) {
key.push(locString(l));
});
key = key.join(':');
index = meta.seen[key];
if (index === undefined) {
index = meta.last.b;
meta.last.b += 1;
meta.seen[key] = index;
this.branchMap[index] = {
loc: loc,
type: type,
locations: branchLocations.map(function (l) {
return that.cloneLocation(l);
})
};
}
if (!this.b[index]) {
this.b[index] = [];
branchLocations.forEach(function () {
that.b[index].push(0);
});
}
for (i = 0; i < hits.length; i += 1) {
that.b[index][i] += hits[i];
}
return index;
};
// returns a clone of the location object with only
// the attributes of interest
MappedCoverage.prototype.cloneLocation = function (loc) {
return {
start: {
line: loc.start.line,
column: loc.start.column
},
end: {
line: loc.end.line,
column: loc.end.column
}
};
};
module.exports = {
MappedCoverage: MappedCoverage
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 1 1 1 1 | var path = require('path'),
isAbsolute = function (p) {
if (path.isAbsolute) {
return path.isAbsolute(p);
}
return path.resolve(p) === path.normalize(p);
};
exports.isAbsolute = isAbsolute;
exports.asAbsolute = function (file, baseDir) {
return isAbsolute(file) ? file : path.resolve(baseDir || process.cwd, file);
};
exports.relativeTo = function (file, origFile) {
return isAbsolute(file) ? file : path.resolve(path.dirname(origFile), file);
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var util = require('util'),
os = require('os'),
path = require('path'),
mkdirp = require('mkdirp'),
rimraf = require('rimraf'),
fs = require('fs');
function SourceStore(/*opts*/) {
}
SourceStore.prototype.registerSource = function (/* filePath, sourceText */) {
throw new Error('registerSource must be overridden');
};
SourceStore.prototype.getSource = function (/* filePath */) {
throw new Error('getSource must be overridden');
};
SourceStore.prototype.dispose = function () {
};
function MemoryStore() {
this.data = {};
}
util.inherits(MemoryStore, SourceStore);
MemoryStore.prototype.registerSource = function (filePath, sourceText) {
this.data[filePath] = sourceText;
};
MemoryStore.prototype.getSource = function (filePath) {
return this.data[filePath] || null;
};
function FileStore(opts) {
opts = opts || {};
var tmpDir = opts.tmpdir || os.tmpdir();
this.counter = 0;
this.mappings = [];
this.basePath = path.resolve(tmpDir, '.istanbul', 'cache_');
mkdirp.sync(path.dirname(this.basePath));
}
util.inherits(FileStore, SourceStore);
FileStore.prototype.registerSource = function (filePath, sourceText) {
if (this.mappings[filePath]) {
return;
}
this.counter += 1;
var mapFile = this.basePath + this.counter;
this.mappings[filePath] = mapFile;
fs.writeFileSync(mapFile, sourceText, 'utf8');
};
FileStore.prototype.getSource = function (filePath) {
var mapFile = this.mappings[filePath];
if (!mapFile) {
return null;
}
return fs.readFileSync(mapFile, 'utf8');
};
FileStore.prototype.dispose = function () {
this.mappings = [];
rimraf.sync(path.dirname(this.basePath));
};
module.exports = {
create: function (type, opts) {
opts = opts || {};
type = (type || 'memory').toLowerCase();
if (type === 'file') {
return new FileStore(opts);
}
return new MemoryStore(opts);
}
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | 1 1 1 1 1 1 1 1 1 1 | /*
Copyright 2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
"use strict";
var pathutils = require('./pathutils'),
libCoverage = require('istanbul-lib-coverage'),
MappedCoverage = require('./mapped').MappedCoverage;
function isInvalidPosition (pos) {
return !pos || typeof pos.line !== "number" || typeof pos.column !== "number" || pos.line < 0 || pos.column < 0;
}
/**
* determines the original position for a given location
* @param {SourceMapConsumer} sourceMap the source map
* @param {Object} location the original location Object
* @returns {Object} the remapped location Object
*/
function getMapping(sourceMap, location, origFile) {
if (!location) {
return null;
}
if (isInvalidPosition(location.start) || isInvalidPosition(location.end)) {
return null;
}
var start = sourceMap.originalPositionFor(location.start),
end = sourceMap.originalPositionFor(location.end);
/* istanbul ignore if: edge case too hard to test for */
if (!(start && end)) {
return null;
}
if (!(start.source && end.source)) {
return null;
}
if (start.source !== end.source) {
return null;
}
/* istanbul ignore if: edge case too hard to test for */
if (start.line === null || start.column === null) {
return null;
}
/* istanbul ignore if: edge case too hard to test for */
if (end.line === null || end.column === null) {
return null;
}
if (start.line === end.line && start.column === end.column) {
end = sourceMap.originalPositionFor({
line: location.end.line,
column: location.end.column,
bias: 2
});
end.column = end.column - 1;
}
return {
source: pathutils.relativeTo(start.source, origFile),
loc: {
start: {
line: start.line,
column: start.column
},
end: {
line: end.line,
column: end.column
}
}
};
}
function SourceMapTransformer(finder, opts) {
opts = opts || {};
this.finder = finder;
this.baseDir = opts.baseDir || process.cwd();
}
SourceMapTransformer.prototype.processFile = function (fc, sourceMap, coverageMapper) {
var changes = 0;
Object.keys(fc.statementMap).forEach(function (s) {
var loc = fc.statementMap[s],
hits = fc.s[s],
mapping = getMapping(sourceMap, loc, fc.path),
mappedCoverage;
if (mapping) {
changes += 1;
mappedCoverage = coverageMapper(mapping.source);
mappedCoverage.addStatement(mapping.loc, hits);
}
});
Object.keys(fc.fnMap).forEach(function (f) {
var fnMeta = fc.fnMap[f],
hits = fc.f[f],
mapping = getMapping(sourceMap, fnMeta.decl, fc.path),
spanMapping = getMapping(sourceMap, fnMeta.loc, fc.path),
mappedCoverage;
if (mapping && spanMapping && mapping.source === spanMapping.source) {
changes += 1;
mappedCoverage = coverageMapper(mapping.source);
mappedCoverage.addFunction(fnMeta.name, mapping.loc, spanMapping.loc, hits);
}
});
Object.keys(fc.branchMap).forEach(function (b) {
var branchMeta = fc.branchMap[b],
source,
hits = fc.b[b],
mapping,
locs = [],
mappedHits = [],
mappedCoverage,
skip,
i;
for (i = 0; i < branchMeta.locations.length; i += 1) {
mapping = getMapping(sourceMap, branchMeta.locations[i], fc.path);
if (mapping) {
if (!source) {
source = mapping.source;
}
if (mapping.source !== source) {
skip = true;
}
locs.push(mapping.loc);
mappedHits.push(hits[i]);
}
}
if (!skip && locs.length > 0) {
changes += 1;
mappedCoverage = coverageMapper(source);
mappedCoverage.addBranch(branchMeta.type, locs[0] /* XXX */, locs, mappedHits);
}
});
return changes > 0;
};
SourceMapTransformer.prototype.transform = function (coverageMap) {
var that = this,
finder = this.finder,
output = {},
getMappedCoverage = function (file) {
if (!output[file]) {
output[file] = new MappedCoverage(file);
}
return output[file];
};
coverageMap.files().forEach(function (file) {
var fc = coverageMap.fileCoverageFor(file),
sourceMap = finder(file),
changed;
if (!sourceMap) {
output[file] = fc;
return;
}
changed = that.processFile(fc, sourceMap, getMappedCoverage);
if (!changed) {
console.warn('File [' + file + '] ignored, nothing could be mapped');
}
});
return libCoverage.createCoverageMap(output);
};
module.exports = {
create: function (finder, opts) {
return new SourceMapTransformer(finder, opts);
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 40% | (2 / 5) | 0% | (0 / 2) | 0% | (0 / 1) | 40% | (2 / 5) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 1 1 | /*
Copyright 2012-2015, Yahoo Inc.
Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
*/
var path = require('path');
module.exports = {
create: function (name, cfg) {
cfg = cfg || {};
var Cons = require(path.join(__dirname, 'lib', name));
return new Cons(cfg);
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 4.92% | (3 / 61) | 0% | (0 / 69) | 0% | (0 / 1) | 4.92% | (3 / 61) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | 1 1 1 | var isBuffer = require('is-buffer');
var toString = Object.prototype.toString;
/**
* Get the native `typeof` a value.
*
* @param {*} `val`
* @return {*} Native javascript type
*/
module.exports = function kindOf(val) {
// primitivies
if (typeof val === 'undefined') {
return 'undefined';
}
if (val === null) {
return 'null';
}
if (val === true || val === false || val instanceof Boolean) {
return 'boolean';
}
if (typeof val === 'string' || val instanceof String) {
return 'string';
}
if (typeof val === 'number' || val instanceof Number) {
return 'number';
}
// functions
if (typeof val === 'function' || val instanceof Function) {
return 'function';
}
// array
if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) {
return 'array';
}
// check for instances of RegExp and Date before calling `toString`
if (val instanceof RegExp) {
return 'regexp';
}
if (val instanceof Date) {
return 'date';
}
// other objects
var type = toString.call(val);
if (type === '[object RegExp]') {
return 'regexp';
}
if (type === '[object Date]') {
return 'date';
}
if (type === '[object Arguments]') {
return 'arguments';
}
if (type === '[object Error]') {
return 'error';
}
// buffer
if (typeof Buffer !== 'undefined' && isBuffer(val)) {
return 'buffer';
}
// es6: Map, WeakMap, Set, WeakSet
if (type === '[object Set]') {
return 'set';
}
if (type === '[object WeakSet]') {
return 'weakset';
}
if (type === '[object Map]') {
return 'map';
}
if (type === '[object WeakMap]') {
return 'weakmap';
}
if (type === '[object Symbol]') {
return 'symbol';
}
// typed arrays
if (type === '[object Int8Array]') {
return 'int8array';
}
if (type === '[object Uint8Array]') {
return 'uint8array';
}
if (type === '[object Uint8ClampedArray]') {
return 'uint8clampedarray';
}
if (type === '[object Int16Array]') {
return 'int16array';
}
if (type === '[object Uint16Array]') {
return 'uint16array';
}
if (type === '[object Int32Array]') {
return 'int32array';
}
if (type === '[object Uint32Array]') {
return 'uint32array';
}
if (type === '[object Float32Array]') {
return 'float32array';
}
if (type === '[object Float64Array]') {
return 'float64array';
}
// must be a plain object
return 'object';
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 69.23% | (9 / 13) | 100% | (0 / 0) | 0% | (0 / 4) | 69.23% | (9 / 13) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 1 1 1 1 1 1 1 1 1 | 'use strict';
var path = require('path');
var fs = require('graceful-fs');
var stripBom = require('strip-bom');
var parseJson = require('parse-json');
var Promise = require('pinkie-promise');
var pify = require('pify');
function parse(x, fp) {
return parseJson(stripBom(x), path.relative(process.cwd(), fp));
}
module.exports = function (fp) {
return pify(fs.readFile, Promise)(fp, 'utf8').then(function (data) {
return parse(data, fp);
});
};
module.exports.sync = function (fp) {
return parse(fs.readFileSync(fp, 'utf8'), fp);
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 16.67% | (2 / 12) | 0% | (0 / 6) | 0% | (0 / 2) | 16.67% | (2 / 12) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 1 1 | 'use strict';
var crypto = require('crypto');
module.exports = function (input) {
var hash = crypto.createHash('md5');
var update = function (buf) {
var inputEncoding = typeof buf === 'string' ? 'utf8' : undefined;
hash.update(buf, inputEncoding);
};
if (arguments.length > 1) {
throw new Error('Too many arguments. Try specifying an array.');
}
if (Array.isArray(input)) {
input.forEach(update);
} else {
update(input);
}
return hash.digest('hex');
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 14.88% | (25 / 168) | 0% | (0 / 116) | 0% | (0 / 15) | 15.34% | (25 / 163) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*!
* micromatch <https://github.com/jonschlinkert/micromatch>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var expand = require('./lib/expand');
var utils = require('./lib/utils');
/**
* The main function. Pass an array of filepaths,
* and a string or array of glob patterns
*
* @param {Array|String} `files`
* @param {Array|String} `patterns`
* @param {Object} `opts`
* @return {Array} Array of matches
*/
function micromatch(files, patterns, opts) {
if (!files || !patterns) return [];
opts = opts || {};
if (typeof opts.cache === 'undefined') {
opts.cache = true;
}
if (!Array.isArray(patterns)) {
return match(files, patterns, opts);
}
var len = patterns.length, i = 0;
var omit = [], keep = [];
while (len--) {
var glob = patterns[i++];
if (typeof glob === 'string' && glob.charCodeAt(0) === 33 /* ! */) {
omit.push.apply(omit, match(files, glob.slice(1), opts));
} else {
keep.push.apply(keep, match(files, glob, opts));
}
}
return utils.diff(keep, omit);
}
/**
* Return an array of files that match the given glob pattern.
*
* This function is called by the main `micromatch` function If you only
* need to pass a single pattern you might get very minor speed improvements
* using this function.
*
* @param {Array} `files`
* @param {String} `pattern`
* @param {Object} `options`
* @return {Array}
*/
function match(files, pattern, opts) {
if (utils.typeOf(files) !== 'string' && !Array.isArray(files)) {
throw new Error(msg('match', 'files', 'a string or array'));
}
files = utils.arrayify(files);
opts = opts || {};
var negate = opts.negate || false;
var orig = pattern;
if (typeof pattern === 'string') {
negate = pattern.charAt(0) === '!';
if (negate) {
pattern = pattern.slice(1);
}
// we need to remove the character regardless,
// so the above logic is still needed
if (opts.nonegate === true) {
negate = false;
}
}
var _isMatch = matcher(pattern, opts);
var len = files.length, i = 0;
var res = [];
while (i < len) {
var file = files[i++];
var fp = utils.unixify(file, opts);
if (!_isMatch(fp)) { continue; }
res.push(fp);
}
if (res.length === 0) {
if (opts.failglob === true) {
throw new Error('micromatch.match() found no matches for: "' + orig + '".');
}
if (opts.nonull || opts.nullglob) {
res.push(utils.unescapeGlob(orig));
}
}
// if `negate` was defined, diff negated files
if (negate) { res = utils.diff(files, res); }
// if `ignore` was defined, diff ignored filed
if (opts.ignore && opts.ignore.length) {
pattern = opts.ignore;
opts = utils.omit(opts, ['ignore']);
res = utils.diff(res, micromatch(res, pattern, opts));
}
if (opts.nodupes) {
return utils.unique(res);
}
return res;
}
/**
* Returns a function that takes a glob pattern or array of glob patterns
* to be used with `Array#filter()`. (Internally this function generates
* the matching function using the [matcher] method).
*
* ```js
* var fn = mm.filter('[a-c]');
* ['a', 'b', 'c', 'd', 'e'].filter(fn);
* //=> ['a', 'b', 'c']
* ```
* @param {String|Array} `patterns` Can be a glob or array of globs.
* @param {Options} `opts` Options to pass to the [matcher] method.
* @return {Function} Filter function to be passed to `Array#filter()`.
*/
function filter(patterns, opts) {
if (!Array.isArray(patterns) && typeof patterns !== 'string') {
throw new TypeError(msg('filter', 'patterns', 'a string or array'));
}
patterns = utils.arrayify(patterns);
var len = patterns.length, i = 0;
var patternMatchers = Array(len);
while (i < len) {
patternMatchers[i] = matcher(patterns[i++], opts);
}
return function(fp) {
if (fp == null) return [];
var len = patternMatchers.length, i = 0;
var res = true;
fp = utils.unixify(fp, opts);
while (i < len) {
var fn = patternMatchers[i++];
if (!fn(fp)) {
res = false;
break;
}
}
return res;
};
}
/**
* Returns true if the filepath contains the given
* pattern. Can also return a function for matching.
*
* ```js
* isMatch('foo.md', '*.md', {});
* //=> true
*
* isMatch('*.md', {})('foo.md')
* //=> true
* ```
* @param {String} `fp`
* @param {String} `pattern`
* @param {Object} `opts`
* @return {Boolean}
*/
function isMatch(fp, pattern, opts) {
if (typeof fp !== 'string') {
throw new TypeError(msg('isMatch', 'filepath', 'a string'));
}
fp = utils.unixify(fp, opts);
if (utils.typeOf(pattern) === 'object') {
return matcher(fp, pattern);
}
return matcher(pattern, opts)(fp);
}
/**
* Returns true if the filepath matches the
* given pattern.
*/
function contains(fp, pattern, opts) {
if (typeof fp !== 'string') {
throw new TypeError(msg('contains', 'pattern', 'a string'));
}
opts = opts || {};
opts.contains = (pattern !== '');
fp = utils.unixify(fp, opts);
if (opts.contains && !utils.isGlob(pattern)) {
return fp.indexOf(pattern) !== -1;
}
return matcher(pattern, opts)(fp);
}
/**
* Returns true if a file path matches any of the
* given patterns.
*
* @param {String} `fp` The filepath to test.
* @param {String|Array} `patterns` Glob patterns to use.
* @param {Object} `opts` Options to pass to the `matcher()` function.
* @return {String}
*/
function any(fp, patterns, opts) {
if (!Array.isArray(patterns) && typeof patterns !== 'string') {
throw new TypeError(msg('any', 'patterns', 'a string or array'));
}
patterns = utils.arrayify(patterns);
var len = patterns.length;
fp = utils.unixify(fp, opts);
while (len--) {
var isMatch = matcher(patterns[len], opts);
if (isMatch(fp)) {
return true;
}
}
return false;
}
/**
* Filter the keys of an object with the given `glob` pattern
* and `options`
*
* @param {Object} `object`
* @param {Pattern} `object`
* @return {Array}
*/
function matchKeys(obj, glob, options) {
if (utils.typeOf(obj) !== 'object') {
throw new TypeError(msg('matchKeys', 'first argument', 'an object'));
}
var fn = matcher(glob, options);
var res = {};
for (var key in obj) {
if (obj.hasOwnProperty(key) && fn(key)) {
res[key] = obj[key];
}
}
return res;
}
/**
* Return a function for matching based on the
* given `pattern` and `options`.
*
* @param {String} `pattern`
* @param {Object} `options`
* @return {Function}
*/
function matcher(pattern, opts) {
// pattern is a function
if (typeof pattern === 'function') {
return pattern;
}
// pattern is a regex
if (pattern instanceof RegExp) {
return function(fp) {
return pattern.test(fp);
};
}
if (typeof pattern !== 'string') {
throw new TypeError(msg('matcher', 'pattern', 'a string, regex, or function'));
}
// strings, all the way down...
pattern = utils.unixify(pattern, opts);
// pattern is a non-glob string
if (!utils.isGlob(pattern)) {
return utils.matchPath(pattern, opts);
}
// pattern is a glob string
var re = makeRe(pattern, opts);
// `matchBase` is defined
if (opts && opts.matchBase) {
return utils.hasFilename(re, opts);
}
// `matchBase` is not defined
return function(fp) {
fp = utils.unixify(fp, opts);
return re.test(fp);
};
}
/**
* Create and cache a regular expression for matching
* file paths.
*
* If the leading character in the `glob` is `!`, a negation
* regex is returned.
*
* @param {String} `glob`
* @param {Object} `options`
* @return {RegExp}
*/
function toRegex(glob, options) {
// clone options to prevent mutating the original object
var opts = Object.create(options || {});
var flags = opts.flags || '';
if (opts.nocase && flags.indexOf('i') === -1) {
flags += 'i';
}
var parsed = expand(glob, opts);
// pass in tokens to avoid parsing more than once
opts.negated = opts.negated || parsed.negated;
opts.negate = opts.negated;
glob = wrapGlob(parsed.pattern, opts);
var re;
try {
re = new RegExp(glob, flags);
return re;
} catch (err) {
err.reason = 'micromatch invalid regex: (' + re + ')';
if (opts.strict) throw new SyntaxError(err);
}
// we're only here if a bad pattern was used and the user
// passed `options.silent`, so match nothing
return /$^/;
}
/**
* Create the regex to do the matching. If the leading
* character in the `glob` is `!` a negation regex is returned.
*
* @param {String} `glob`
* @param {Boolean} `negate`
*/
function wrapGlob(glob, opts) {
var prefix = (opts && !opts.contains) ? '^' : '';
var after = (opts && !opts.contains) ? '$' : '';
glob = ('(?:' + glob + ')' + after);
if (opts && opts.negate) {
return prefix + ('(?!^' + glob + ').*$');
}
return prefix + glob;
}
/**
* Create and cache a regular expression for matching file paths.
* If the leading character in the `glob` is `!`, a negation
* regex is returned.
*
* @param {String} `glob`
* @param {Object} `options`
* @return {RegExp}
*/
function makeRe(glob, opts) {
if (utils.typeOf(glob) !== 'string') {
throw new Error(msg('makeRe', 'glob', 'a string'));
}
return utils.cache(toRegex, glob, opts);
}
/**
* Make error messages consistent. Follows this format:
*
* ```js
* msg(methodName, argNumber, nativeType);
* // example:
* msg('matchKeys', 'first', 'an object');
* ```
*
* @param {String} `method`
* @param {String} `num`
* @param {String} `type`
* @return {String}
*/
function msg(method, what, type) {
return 'micromatch.' + method + '(): ' + what + ' should be ' + type + '.';
}
/**
* Public methods
*/
/* eslint no-multi-spaces: 0 */
micromatch.any = any;
micromatch.braces = micromatch.braceExpand = utils.braces;
micromatch.contains = contains;
micromatch.expand = expand;
micromatch.filter = filter;
micromatch.isMatch = isMatch;
micromatch.makeRe = makeRe;
micromatch.match = match;
micromatch.matcher = matcher;
micromatch.matchKeys = matchKeys;
/**
* Expose `micromatch`
*/
module.exports = micromatch;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| chars.js | 100% | (12 / 12) | 100% | (6 / 6) | 100% | (2 / 2) | 100% | (12 / 12) | |
| expand.js | 11.63% | (15 / 129) | 0% | (0 / 78) | 0% | (0 / 8) | 11.9% | (15 / 126) | |
| glob.js | 20% | (15 / 75) | 0% | (0 / 40) | 0% | (0 / 15) | 20.55% | (15 / 73) | |
| utils.js | 50.94% | (27 / 53) | 6.25% | (2 / 32) | 0% | (0 / 13) | 51.92% | (27 / 52) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 1 1 2 20 20 20 1 1 1 1 1 1 | 'use strict';
var chars = {}, unesc, temp;
function reverse(object, prepender) {
return Object.keys(object).reduce(function(reversed, key) {
var newKey = prepender ? prepender + key : key; // Optionally prepend a string to key.
reversed[object[key]] = newKey; // Swap key and value.
return reversed; // Return the result.
}, {});
}
/**
* Regex for common characters
*/
chars.escapeRegex = {
'?': /\?/g,
'@': /\@/g,
'!': /\!/g,
'+': /\+/g,
'*': /\*/g,
'(': /\(/g,
')': /\)/g,
'[': /\[/g,
']': /\]/g
};
/**
* Escape characters
*/
chars.ESC = {
'?': '__UNESC_QMRK__',
'@': '__UNESC_AMPE__',
'!': '__UNESC_EXCL__',
'+': '__UNESC_PLUS__',
'*': '__UNESC_STAR__',
',': '__UNESC_COMMA__',
'(': '__UNESC_LTPAREN__',
')': '__UNESC_RTPAREN__',
'[': '__UNESC_LTBRACK__',
']': '__UNESC_RTBRACK__'
};
/**
* Unescape characters
*/
chars.UNESC = unesc || (unesc = reverse(chars.ESC, '\\'));
chars.ESC_TEMP = {
'?': '__TEMP_QMRK__',
'@': '__TEMP_AMPE__',
'!': '__TEMP_EXCL__',
'*': '__TEMP_STAR__',
'+': '__TEMP_PLUS__',
',': '__TEMP_COMMA__',
'(': '__TEMP_LTPAREN__',
')': '__TEMP_RTPAREN__',
'[': '__TEMP_LTBRACK__',
']': '__TEMP_RTBRACK__'
};
chars.TEMP = temp || (temp = reverse(chars.ESC_TEMP));
module.exports = chars;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*!
* micromatch <https://github.com/jonschlinkert/micromatch>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var utils = require('./utils');
var Glob = require('./glob');
/**
* Expose `expand`
*/
module.exports = expand;
/**
* Expand a glob pattern to resolve braces and
* similar patterns before converting to regex.
*
* @param {String|Array} `pattern`
* @param {Array} `files`
* @param {Options} `opts`
* @return {Array}
*/
function expand(pattern, options) {
if (typeof pattern !== 'string') {
throw new TypeError('micromatch.expand(): argument should be a string.');
}
var glob = new Glob(pattern, options || {});
var opts = glob.options;
if (!utils.isGlob(pattern)) {
glob.pattern = glob.pattern.replace(/([\/.])/g, '\\$1');
return glob;
}
glob.pattern = glob.pattern.replace(/(\+)(?!\()/g, '\\$1');
glob.pattern = glob.pattern.split('$').join('\\$');
if (typeof opts.braces !== 'boolean' && typeof opts.nobraces !== 'boolean') {
opts.braces = true;
}
if (glob.pattern === '.*') {
return {
pattern: '\\.' + star,
tokens: tok,
options: opts
};
}
if (glob.pattern === '*') {
return {
pattern: oneStar(opts.dot),
tokens: tok,
options: opts
};
}
// parse the glob pattern into tokens
glob.parse();
var tok = glob.tokens;
tok.is.negated = opts.negated;
// dotfile handling
if ((opts.dotfiles === true || tok.is.dotfile) && opts.dot !== false) {
opts.dotfiles = true;
opts.dot = true;
}
if ((opts.dotdirs === true || tok.is.dotdir) && opts.dot !== false) {
opts.dotdirs = true;
opts.dot = true;
}
// check for braces with a dotfile pattern
if (/[{,]\./.test(glob.pattern)) {
opts.makeRe = false;
opts.dot = true;
}
if (opts.nonegate !== true) {
opts.negated = glob.negated;
}
// if the leading character is a dot or a slash, escape it
if (glob.pattern.charAt(0) === '.' && glob.pattern.charAt(1) !== '/') {
glob.pattern = '\\' + glob.pattern;
}
/**
* Extended globs
*/
// expand braces, e.g `{1..5}`
glob.track('before braces');
if (tok.is.braces) {
glob.braces();
}
glob.track('after braces');
// expand extglobs, e.g `foo/!(a|b)`
glob.track('before extglob');
if (tok.is.extglob) {
glob.extglob();
}
glob.track('after extglob');
// expand brackets, e.g `[[:alpha:]]`
glob.track('before brackets');
if (tok.is.brackets) {
glob.brackets();
}
glob.track('after brackets');
// special patterns
glob._replace('[!', '[^');
glob._replace('(?', '(%~');
glob._replace(/\[\]/, '\\[\\]');
glob._replace('/[', '/' + (opts.dot ? dotfiles : nodot) + '[', true);
glob._replace('/?', '/' + (opts.dot ? dotfiles : nodot) + '[^/]', true);
glob._replace('/.', '/(?=.)\\.', true);
// windows drives
glob._replace(/^(\w):([\\\/]+?)/gi, '(?=.)$1:$2', true);
// negate slashes in exclusion ranges
if (glob.pattern.indexOf('[^') !== -1) {
glob.pattern = negateSlash(glob.pattern);
}
if (opts.globstar !== false && glob.pattern === '**') {
glob.pattern = globstar(opts.dot);
} else {
glob.pattern = balance(glob.pattern, '[', ']');
glob.escape(glob.pattern);
// if the pattern has `**`
if (tok.is.globstar) {
glob.pattern = collapse(glob.pattern, '/**');
glob.pattern = collapse(glob.pattern, '**/');
glob._replace('/**/', '(?:/' + globstar(opts.dot) + '/|/)', true);
glob._replace(/\*{2,}/g, '**');
// 'foo/*'
glob._replace(/(\w+)\*(?!\/)/g, '$1[^/]*?', true);
glob._replace(/\*\*\/\*(\w)/g, globstar(opts.dot) + '\\/' + (opts.dot ? dotfiles : nodot) + '[^/]*?$1', true);
if (opts.dot !== true) {
glob._replace(/\*\*\/(.)/g, '(?:**\\/|)$1');
}
// 'foo/**' or '{**,*}', but not 'foo**'
if (tok.path.dirname !== '' || /,\*\*|\*\*,/.test(glob.orig)) {
glob._replace('**', globstar(opts.dot), true);
}
}
// ends with /*
glob._replace(/\/\*$/, '\\/' + oneStar(opts.dot), true);
// ends with *, no slashes
glob._replace(/(?!\/)\*$/, star, true);
// has 'n*.' (partial wildcard w/ file extension)
glob._replace(/([^\/]+)\*/, '$1' + oneStar(true), true);
// has '*'
glob._replace('*', oneStar(opts.dot), true);
glob._replace('?.', '?\\.', true);
glob._replace('?:', '?:', true);
glob._replace(/\?+/g, function(match) {
var len = match.length;
if (len === 1) {
return qmark;
}
return qmark + '{' + len + '}';
});
// escape '.abc' => '\\.abc'
glob._replace(/\.([*\w]+)/g, '\\.$1');
// fix '[^\\\\/]'
glob._replace(/\[\^[\\\/]+\]/g, qmark);
// '///' => '\/'
glob._replace(/\/+/g, '\\/');
// '\\\\\\' => '\\'
glob._replace(/\\{2,}/g, '\\');
}
// unescape previously escaped patterns
glob.unescape(glob.pattern);
glob._replace('__UNESC_STAR__', '*');
// escape dots that follow qmarks
glob._replace('?.', '?\\.');
// remove unnecessary slashes in character classes
glob._replace('[^\\/]', qmark);
if (glob.pattern.length > 1) {
if (/^[\[?*]/.test(glob.pattern)) {
// only prepend the string if we don't want to match dotfiles
glob.pattern = (opts.dot ? dotfiles : nodot) + glob.pattern;
}
}
return glob;
}
/**
* Collapse repeated character sequences.
*
* ```js
* collapse('a/../../../b', '../');
* //=> 'a/../b'
* ```
*
* @param {String} `str`
* @param {String} `ch` Character sequence to collapse
* @return {String}
*/
function collapse(str, ch) {
var res = str.split(ch);
var isFirst = res[0] === '';
var isLast = res[res.length - 1] === '';
res = res.filter(Boolean);
if (isFirst) res.unshift('');
if (isLast) res.push('');
return res.join(ch);
}
/**
* Negate slashes in exclusion ranges, per glob spec:
*
* ```js
* negateSlash('[^foo]');
* //=> '[^\\/foo]'
* ```
*
* @param {String} `str` glob pattern
* @return {String}
*/
function negateSlash(str) {
return str.replace(/\[\^([^\]]*?)\]/g, function(match, inner) {
if (inner.indexOf('/') === -1) {
inner = '\\/' + inner;
}
return '[^' + inner + ']';
});
}
/**
* Escape imbalanced braces/bracket. This is a very
* basic, naive implementation that only does enough
* to serve the purpose.
*/
function balance(str, a, b) {
var aarr = str.split(a);
var alen = aarr.join('').length;
var blen = str.split(b).join('').length;
if (alen !== blen) {
str = aarr.join('\\' + a);
return str.split(b).join('\\' + b);
}
return str;
}
/**
* Special patterns to be converted to regex.
* Heuristics are used to simplify patterns
* and speed up processing.
*/
/* eslint no-multi-spaces: 0 */
var qmark = '[^/]';
var star = qmark + '*?';
var nodot = '(?!\\.)(?=.)';
var dotfileGlob = '(?:\\/|^)\\.{1,2}($|\\/)';
var dotfiles = '(?!' + dotfileGlob + ')(?=.)';
var twoStarDot = '(?:(?!' + dotfileGlob + ').)*?';
/**
* Create a regex for `*`.
*
* If `dot` is true, or the pattern does not begin with
* a leading star, then return the simpler regex.
*/
function oneStar(dotfile) {
return dotfile ? '(?!' + dotfileGlob + ')(?=.)' + star : (nodot + star);
}
function globstar(dotfile) {
if (dotfile) { return twoStarDot; }
return '(?:(?!(?:\\/|^)\\.).)*?';
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var chars = require('./chars');
var utils = require('./utils');
/**
* Expose `Glob`
*/
var Glob = module.exports = function Glob(pattern, options) {
if (!(this instanceof Glob)) {
return new Glob(pattern, options);
}
this.options = options || {};
this.pattern = pattern;
this.history = [];
this.tokens = {};
this.init(pattern);
};
/**
* Initialize defaults
*/
Glob.prototype.init = function(pattern) {
this.orig = pattern;
this.negated = this.isNegated();
this.options.track = this.options.track || false;
this.options.makeRe = true;
};
/**
* Push a change into `glob.history`. Useful
* for debugging.
*/
Glob.prototype.track = function(msg) {
if (this.options.track) {
this.history.push({msg: msg, pattern: this.pattern});
}
};
/**
* Return true if `glob.pattern` was negated
* with `!`, also remove the `!` from the pattern.
*
* @return {Boolean}
*/
Glob.prototype.isNegated = function() {
if (this.pattern.charCodeAt(0) === 33 /* '!' */) {
this.pattern = this.pattern.slice(1);
return true;
}
return false;
};
/**
* Expand braces in the given glob pattern.
*
* We only need to use the [braces] lib when
* patterns are nested.
*/
Glob.prototype.braces = function() {
if (this.options.nobraces !== true && this.options.nobrace !== true) {
// naive/fast check for imbalanced characters
var a = this.pattern.match(/[\{\(\[]/g);
var b = this.pattern.match(/[\}\)\]]/g);
// if imbalanced, don't optimize the pattern
if (a && b && (a.length !== b.length)) {
this.options.makeRe = false;
}
// expand brace patterns and join the resulting array
var expanded = utils.braces(this.pattern, this.options);
this.pattern = expanded.join('|');
}
};
/**
* Expand bracket expressions in `glob.pattern`
*/
Glob.prototype.brackets = function() {
if (this.options.nobrackets !== true) {
this.pattern = utils.brackets(this.pattern);
}
};
/**
* Expand bracket expressions in `glob.pattern`
*/
Glob.prototype.extglob = function() {
if (this.options.noextglob === true) return;
if (utils.isExtglob(this.pattern)) {
this.pattern = utils.extglob(this.pattern, {escape: true});
}
};
/**
* Parse the given pattern
*/
Glob.prototype.parse = function(pattern) {
this.tokens = utils.parseGlob(pattern || this.pattern, true);
return this.tokens;
};
/**
* Replace `a` with `b`. Also tracks the change before and
* after each replacement. This is disabled by default, but
* can be enabled by setting `options.track` to true.
*
* Also, when the pattern is a string, `.split()` is used,
* because it's much faster than replace.
*
* @param {RegExp|String} `a`
* @param {String} `b`
* @param {Boolean} `escape` When `true`, escapes `*` and `?` in the replacement.
* @return {String}
*/
Glob.prototype._replace = function(a, b, escape) {
this.track('before (find): "' + a + '" (replace with): "' + b + '"');
if (escape) b = esc(b);
if (a && b && typeof a === 'string') {
this.pattern = this.pattern.split(a).join(b);
} else {
this.pattern = this.pattern.replace(a, b);
}
this.track('after');
};
/**
* Escape special characters in the given string.
*
* @param {String} `str` Glob pattern
* @return {String}
*/
Glob.prototype.escape = function(str) {
this.track('before escape: ');
var re = /["\\](['"]?[^"'\\]['"]?)/g;
this.pattern = str.replace(re, function($0, $1) {
var o = chars.ESC;
var ch = o && o[$1];
if (ch) {
return ch;
}
if (/[a-z]/i.test($0)) {
return $0.split('\\').join('');
}
return $0;
});
this.track('after escape: ');
};
/**
* Unescape special characters in the given string.
*
* @param {String} `str`
* @return {String}
*/
Glob.prototype.unescape = function(str) {
var re = /__([A-Z]+)_([A-Z]+)__/g;
this.pattern = str.replace(re, function($0, $1) {
return chars[$1][$0];
});
this.pattern = unesc(this.pattern);
};
/**
* Escape/unescape utils
*/
function esc(str) {
str = str.split('?').join('%~');
str = str.split('*').join('%%');
return str;
}
function unesc(str) {
str = str.split('%~').join('?');
str = str.split('%%').join('*');
return str;
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var win32 = process && process.platform === 'win32';
var path = require('path');
var fileRe = require('filename-regex');
var utils = module.exports;
/**
* Module dependencies
*/
utils.diff = require('arr-diff');
utils.unique = require('array-unique');
utils.braces = require('braces');
utils.brackets = require('expand-brackets');
utils.extglob = require('extglob');
utils.isExtglob = require('is-extglob');
utils.isGlob = require('is-glob');
utils.typeOf = require('kind-of');
utils.normalize = require('normalize-path');
utils.omit = require('object.omit');
utils.parseGlob = require('parse-glob');
utils.cache = require('regex-cache');
/**
* Get the filename of a filepath
*
* @param {String} `string`
* @return {String}
*/
utils.filename = function filename(fp) {
var seg = fp.match(fileRe());
return seg && seg[0];
};
/**
* Returns a function that returns true if the given
* pattern is the same as a given `filepath`
*
* @param {String} `pattern`
* @return {Function}
*/
utils.isPath = function isPath(pattern, opts) {
opts = opts || {};
return function(fp) {
var unixified = utils.unixify(fp, opts);
if(opts.nocase){
return pattern.toLowerCase() === unixified.toLowerCase();
}
return pattern === unixified;
};
};
/**
* Returns a function that returns true if the given
* pattern contains a `filepath`
*
* @param {String} `pattern`
* @return {Function}
*/
utils.hasPath = function hasPath(pattern, opts) {
return function(fp) {
return utils.unixify(pattern, opts).indexOf(fp) !== -1;
};
};
/**
* Returns a function that returns true if the given
* pattern matches or contains a `filepath`
*
* @param {String} `pattern`
* @return {Function}
*/
utils.matchPath = function matchPath(pattern, opts) {
var fn = (opts && opts.contains)
? utils.hasPath(pattern, opts)
: utils.isPath(pattern, opts);
return fn;
};
/**
* Returns a function that returns true if the given
* regex matches the `filename` of a file path.
*
* @param {RegExp} `re`
* @return {Boolean}
*/
utils.hasFilename = function hasFilename(re) {
return function(fp) {
var name = utils.filename(fp);
return name && re.test(name);
};
};
/**
* Coerce `val` to an array
*
* @param {*} val
* @return {Array}
*/
utils.arrayify = function arrayify(val) {
return !Array.isArray(val)
? [val]
: val;
};
/**
* Normalize all slashes in a file path or glob pattern to
* forward slashes.
*/
utils.unixify = function unixify(fp, opts) {
if (opts && opts.unixify === false) return fp;
if (opts && opts.unixify === true || win32 || path.sep === '\\') {
return utils.normalize(fp, false);
}
if (opts && opts.unescape === true) {
return fp ? fp.toString().replace(/\\(\w)/g, '$1') : '';
}
return fp;
};
/**
* Escape/unescape utils
*/
utils.escapePath = function escapePath(fp) {
return fp.replace(/[\\.]/g, '\\$&');
};
utils.unescapeGlob = function unescapeGlob(fp) {
return fp.replace(/[\\"']/g, '');
};
utils.escapeRe = function escapeRe(str) {
return str.replace(/[-[\\$*+?.#^\s{}(|)\]]/g, '\\$&');
};
/**
* Expose `utils`
*/
module.exports = utils;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| minimatch.js | 10.77% | (46 / 427) | 0% | (0 / 260) | 5.88% | (2 / 34) | 11.41% | (46 / 403) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14 14 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | module.exports = minimatch
minimatch.Minimatch = Minimatch
var path = { sep: '/' }
try {
path = require('path')
} catch (er) {}
var GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
var expand = require('brace-expansion')
var plTypes = {
'!': { open: '(?:(?!(?:', close: '))[^/]*?)'},
'?': { open: '(?:', close: ')?' },
'+': { open: '(?:', close: ')+' },
'*': { open: '(?:', close: ')*' },
'@': { open: '(?:', close: ')' }
}
// any single thing other than /
// don't need to escape / when using new RegExp()
var qmark = '[^/]'
// * => any number of characters
var star = qmark + '*?'
// ** when dots are allowed. Anything goes, except .. and .
// not (^ or / followed by one or two dots followed by $ or /),
// followed by anything, any number of times.
var twoStarDot = '(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?'
// not a ^ or / followed by a dot,
// followed by anything, any number of times.
var twoStarNoDot = '(?:(?!(?:\\\/|^)\\.).)*?'
// characters that need to be escaped in RegExp.
var reSpecials = charSet('().*{}+?[]^$\\!')
// "abc" -> { a:true, b:true, c:true }
function charSet (s) {
return s.split('').reduce(function (set, c) {
set[c] = true
return set
}, {})
}
// normalizes slashes.
var slashSplit = /\/+/
minimatch.filter = filter
function filter (pattern, options) {
options = options || {}
return function (p, i, list) {
return minimatch(p, pattern, options)
}
}
function ext (a, b) {
a = a || {}
b = b || {}
var t = {}
Object.keys(b).forEach(function (k) {
t[k] = b[k]
})
Object.keys(a).forEach(function (k) {
t[k] = a[k]
})
return t
}
minimatch.defaults = function (def) {
if (!def || !Object.keys(def).length) return minimatch
var orig = minimatch
var m = function minimatch (p, pattern, options) {
return orig.minimatch(p, pattern, ext(def, options))
}
m.Minimatch = function Minimatch (pattern, options) {
return new orig.Minimatch(pattern, ext(def, options))
}
return m
}
Minimatch.defaults = function (def) {
if (!def || !Object.keys(def).length) return Minimatch
return minimatch.defaults(def).Minimatch
}
function minimatch (p, pattern, options) {
if (typeof pattern !== 'string') {
throw new TypeError('glob pattern string required')
}
if (!options) options = {}
// shortcut: comments match nothing.
if (!options.nocomment && pattern.charAt(0) === '#') {
return false
}
// "" only matches ""
if (pattern.trim() === '') return p === ''
return new Minimatch(pattern, options).match(p)
}
function Minimatch (pattern, options) {
if (!(this instanceof Minimatch)) {
return new Minimatch(pattern, options)
}
if (typeof pattern !== 'string') {
throw new TypeError('glob pattern string required')
}
if (!options) options = {}
pattern = pattern.trim()
// windows support: need to use /, not \
if (path.sep !== '/') {
pattern = pattern.split(path.sep).join('/')
}
this.options = options
this.set = []
this.pattern = pattern
this.regexp = null
this.negate = false
this.comment = false
this.empty = false
// make the set of regexps etc.
this.make()
}
Minimatch.prototype.debug = function () {}
Minimatch.prototype.make = make
function make () {
// don't do it more than once.
if (this._made) return
var pattern = this.pattern
var options = this.options
// empty patterns and comments match nothing.
if (!options.nocomment && pattern.charAt(0) === '#') {
this.comment = true
return
}
if (!pattern) {
this.empty = true
return
}
// step 1: figure out negation, etc.
this.parseNegate()
// step 2: expand braces
var set = this.globSet = this.braceExpand()
if (options.debug) this.debug = console.error
this.debug(this.pattern, set)
// step 3: now we have a set, so turn each one into a series of path-portion
// matching patterns.
// These will be regexps, except in the case of "**", which is
// set to the GLOBSTAR object for globstar behavior,
// and will not contain any / characters
set = this.globParts = set.map(function (s) {
return s.split(slashSplit)
})
this.debug(this.pattern, set)
// glob --> regexps
set = set.map(function (s, si, set) {
return s.map(this.parse, this)
}, this)
this.debug(this.pattern, set)
// filter out everything that didn't compile properly.
set = set.filter(function (s) {
return s.indexOf(false) === -1
})
this.debug(this.pattern, set)
this.set = set
}
Minimatch.prototype.parseNegate = parseNegate
function parseNegate () {
var pattern = this.pattern
var negate = false
var options = this.options
var negateOffset = 0
if (options.nonegate) return
for (var i = 0, l = pattern.length
; i < l && pattern.charAt(i) === '!'
; i++) {
negate = !negate
negateOffset++
}
if (negateOffset) this.pattern = pattern.substr(negateOffset)
this.negate = negate
}
// Brace expansion:
// a{b,c}d -> abd acd
// a{b,}c -> abc ac
// a{0..3}d -> a0d a1d a2d a3d
// a{b,c{d,e}f}g -> abg acdfg acefg
// a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
//
// Invalid sets are not expanded.
// a{2..}b -> a{2..}b
// a{b}c -> a{b}c
minimatch.braceExpand = function (pattern, options) {
return braceExpand(pattern, options)
}
Minimatch.prototype.braceExpand = braceExpand
function braceExpand (pattern, options) {
if (!options) {
if (this instanceof Minimatch) {
options = this.options
} else {
options = {}
}
}
pattern = typeof pattern === 'undefined'
? this.pattern : pattern
if (typeof pattern === 'undefined') {
throw new TypeError('undefined pattern')
}
if (options.nobrace ||
!pattern.match(/\{.*\}/)) {
// shortcut. no need to expand.
return [pattern]
}
return expand(pattern)
}
// parse a component of the expanded set.
// At this point, no pattern may contain "/" in it
// so we're going to return a 2d array, where each entry is the full
// pattern, split on '/', and then turned into a regular expression.
// A regexp is made at the end which joins each array with an
// escaped /, and another full one which joins each regexp with |.
//
// Following the lead of Bash 4.1, note that "**" only has special meaning
// when it is the *only* thing in a path portion. Otherwise, any series
// of * is equivalent to a single *. Globstar behavior is enabled by
// default, and can be disabled by setting options.noglobstar.
Minimatch.prototype.parse = parse
var SUBPARSE = {}
function parse (pattern, isSub) {
if (pattern.length > 1024 * 64) {
throw new TypeError('pattern is too long')
}
var options = this.options
// shortcuts
if (!options.noglobstar && pattern === '**') return GLOBSTAR
if (pattern === '') return ''
var re = ''
var hasMagic = !!options.nocase
var escaping = false
// ? => one single character
var patternListStack = []
var negativeLists = []
var stateChar
var inClass = false
var reClassStart = -1
var classStart = -1
// . and .. never match anything that doesn't start with .,
// even when options.dot is set.
var patternStart = pattern.charAt(0) === '.' ? '' // anything
// not (start or / followed by . or .. followed by / or end)
: options.dot ? '(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))'
: '(?!\\.)'
var self = this
function clearStateChar () {
if (stateChar) {
// we had some state-tracking character
// that wasn't consumed by this pass.
switch (stateChar) {
case '*':
re += star
hasMagic = true
break
case '?':
re += qmark
hasMagic = true
break
default:
re += '\\' + stateChar
break
}
self.debug('clearStateChar %j %j', stateChar, re)
stateChar = false
}
}
for (var i = 0, len = pattern.length, c
; (i < len) && (c = pattern.charAt(i))
; i++) {
this.debug('%s\t%s %s %j', pattern, i, re, c)
// skip over any that are escaped.
if (escaping && reSpecials[c]) {
re += '\\' + c
escaping = false
continue
}
switch (c) {
case '/':
// completely not allowed, even escaped.
// Should already be path-split by now.
return false
case '\\':
clearStateChar()
escaping = true
continue
// the various stateChar values
// for the "extglob" stuff.
case '?':
case '*':
case '+':
case '@':
case '!':
this.debug('%s\t%s %s %j <-- stateChar', pattern, i, re, c)
// all of those are literals inside a class, except that
// the glob [!a] means [^a] in regexp
if (inClass) {
this.debug(' in class')
if (c === '!' && i === classStart + 1) c = '^'
re += c
continue
}
// if we already have a stateChar, then it means
// that there was something like ** or +? in there.
// Handle the stateChar, then proceed with this one.
self.debug('call clearStateChar %j', stateChar)
clearStateChar()
stateChar = c
// if extglob is disabled, then +(asdf|foo) isn't a thing.
// just clear the statechar *now*, rather than even diving into
// the patternList stuff.
if (options.noext) clearStateChar()
continue
case '(':
if (inClass) {
re += '('
continue
}
if (!stateChar) {
re += '\\('
continue
}
patternListStack.push({
type: stateChar,
start: i - 1,
reStart: re.length,
open: plTypes[stateChar].open,
close: plTypes[stateChar].close
})
// negation is (?:(?!js)[^/]*)
re += stateChar === '!' ? '(?:(?!(?:' : '(?:'
this.debug('plType %j %j', stateChar, re)
stateChar = false
continue
case ')':
if (inClass || !patternListStack.length) {
re += '\\)'
continue
}
clearStateChar()
hasMagic = true
var pl = patternListStack.pop()
// negation is (?:(?!js)[^/]*)
// The others are (?:<pattern>)<type>
re += pl.close
if (pl.type === '!') {
negativeLists.push(pl)
}
pl.reEnd = re.length
continue
case '|':
if (inClass || !patternListStack.length || escaping) {
re += '\\|'
escaping = false
continue
}
clearStateChar()
re += '|'
continue
// these are mostly the same in regexp and glob
case '[':
// swallow any state-tracking char before the [
clearStateChar()
if (inClass) {
re += '\\' + c
continue
}
inClass = true
classStart = i
reClassStart = re.length
re += c
continue
case ']':
// a right bracket shall lose its special
// meaning and represent itself in
// a bracket expression if it occurs
// first in the list. -- POSIX.2 2.8.3.2
if (i === classStart + 1 || !inClass) {
re += '\\' + c
escaping = false
continue
}
// handle the case where we left a class open.
// "[z-a]" is valid, equivalent to "\[z-a\]"
if (inClass) {
// split where the last [ was, make sure we don't have
// an invalid re. if so, re-walk the contents of the
// would-be class to re-translate any characters that
// were passed through as-is
// TODO: It would probably be faster to determine this
// without a try/catch and a new RegExp, but it's tricky
// to do safely. For now, this is safe and works.
var cs = pattern.substring(classStart + 1, i)
try {
RegExp('[' + cs + ']')
} catch (er) {
// not a valid class!
var sp = this.parse(cs, SUBPARSE)
re = re.substr(0, reClassStart) + '\\[' + sp[0] + '\\]'
hasMagic = hasMagic || sp[1]
inClass = false
continue
}
}
// finish up the class.
hasMagic = true
inClass = false
re += c
continue
default:
// swallow any state char that wasn't consumed
clearStateChar()
if (escaping) {
// no need
escaping = false
} else if (reSpecials[c]
&& !(c === '^' && inClass)) {
re += '\\'
}
re += c
} // switch
} // for
// handle the case where we left a class open.
// "[abc" is valid, equivalent to "\[abc"
if (inClass) {
// split where the last [ was, and escape it
// this is a huge pita. We now have to re-walk
// the contents of the would-be class to re-translate
// any characters that were passed through as-is
cs = pattern.substr(classStart + 1)
sp = this.parse(cs, SUBPARSE)
re = re.substr(0, reClassStart) + '\\[' + sp[0]
hasMagic = hasMagic || sp[1]
}
// handle the case where we had a +( thing at the *end*
// of the pattern.
// each pattern list stack adds 3 chars, and we need to go through
// and escape any | chars that were passed through as-is for the regexp.
// Go through and escape them, taking care not to double-escape any
// | chars that were already escaped.
for (pl = patternListStack.pop(); pl; pl = patternListStack.pop()) {
var tail = re.slice(pl.reStart + pl.open.length)
this.debug('setting tail', re, pl)
// maybe some even number of \, then maybe 1 \, followed by a |
tail = tail.replace(/((?:\\{2}){0,64})(\\?)\|/g, function (_, $1, $2) {
if (!$2) {
// the | isn't already escaped, so escape it.
$2 = '\\'
}
// need to escape all those slashes *again*, without escaping the
// one that we need for escaping the | character. As it works out,
// escaping an even number of slashes can be done by simply repeating
// it exactly after itself. That's why this trick works.
//
// I am sorry that you have to see this.
return $1 + $1 + $2 + '|'
})
this.debug('tail=%j\n %s', tail, tail, pl, re)
var t = pl.type === '*' ? star
: pl.type === '?' ? qmark
: '\\' + pl.type
hasMagic = true
re = re.slice(0, pl.reStart) + t + '\\(' + tail
}
// handle trailing things that only matter at the very end.
clearStateChar()
if (escaping) {
// trailing \\
re += '\\\\'
}
// only need to apply the nodot start if the re starts with
// something that could conceivably capture a dot
var addPatternStart = false
switch (re.charAt(0)) {
case '.':
case '[':
case '(': addPatternStart = true
}
// Hack to work around lack of negative lookbehind in JS
// A pattern like: *.!(x).!(y|z) needs to ensure that a name
// like 'a.xyz.yz' doesn't match. So, the first negative
// lookahead, has to look ALL the way ahead, to the end of
// the pattern.
for (var n = negativeLists.length - 1; n > -1; n--) {
var nl = negativeLists[n]
var nlBefore = re.slice(0, nl.reStart)
var nlFirst = re.slice(nl.reStart, nl.reEnd - 8)
var nlLast = re.slice(nl.reEnd - 8, nl.reEnd)
var nlAfter = re.slice(nl.reEnd)
nlLast += nlAfter
// Handle nested stuff like *(*.js|!(*.json)), where open parens
// mean that we should *not* include the ) in the bit that is considered
// "after" the negated section.
var openParensBefore = nlBefore.split('(').length - 1
var cleanAfter = nlAfter
for (i = 0; i < openParensBefore; i++) {
cleanAfter = cleanAfter.replace(/\)[+*?]?/, '')
}
nlAfter = cleanAfter
var dollar = ''
if (nlAfter === '' && isSub !== SUBPARSE) {
dollar = '$'
}
var newRe = nlBefore + nlFirst + nlAfter + dollar + nlLast
re = newRe
}
// if the re is not "" at this point, then we need to make sure
// it doesn't match against an empty path part.
// Otherwise a/* will match a/, which it should not.
if (re !== '' && hasMagic) {
re = '(?=.)' + re
}
if (addPatternStart) {
re = patternStart + re
}
// parsing just a piece of a larger pattern.
if (isSub === SUBPARSE) {
return [re, hasMagic]
}
// skip the regexp for non-magical patterns
// unescape anything in it, though, so that it'll be
// an exact match against a file etc.
if (!hasMagic) {
return globUnescape(pattern)
}
var flags = options.nocase ? 'i' : ''
try {
var regExp = new RegExp('^' + re + '$', flags)
} catch (er) {
// If it was an invalid regular expression, then it can't match
// anything. This trick looks for a character after the end of
// the string, which is of course impossible, except in multi-line
// mode, but it's not a /m regex.
return new RegExp('$.')
}
regExp._glob = pattern
regExp._src = re
return regExp
}
minimatch.makeRe = function (pattern, options) {
return new Minimatch(pattern, options || {}).makeRe()
}
Minimatch.prototype.makeRe = makeRe
function makeRe () {
if (this.regexp || this.regexp === false) return this.regexp
// at this point, this.set is a 2d array of partial
// pattern strings, or "**".
//
// It's better to use .match(). This function shouldn't
// be used, really, but it's pretty convenient sometimes,
// when you just want to work with a regex.
var set = this.set
if (!set.length) {
this.regexp = false
return this.regexp
}
var options = this.options
var twoStar = options.noglobstar ? star
: options.dot ? twoStarDot
: twoStarNoDot
var flags = options.nocase ? 'i' : ''
var re = set.map(function (pattern) {
return pattern.map(function (p) {
return (p === GLOBSTAR) ? twoStar
: (typeof p === 'string') ? regExpEscape(p)
: p._src
}).join('\\\/')
}).join('|')
// must match entire pattern
// ending in a * or ** will make it less strict.
re = '^(?:' + re + ')$'
// can match anything, as long as it's not this.
if (this.negate) re = '^(?!' + re + ').*$'
try {
this.regexp = new RegExp(re, flags)
} catch (ex) {
this.regexp = false
}
return this.regexp
}
minimatch.match = function (list, pattern, options) {
options = options || {}
var mm = new Minimatch(pattern, options)
list = list.filter(function (f) {
return mm.match(f)
})
if (mm.options.nonull && !list.length) {
list.push(pattern)
}
return list
}
Minimatch.prototype.match = match
function match (f, partial) {
this.debug('match', f, this.pattern)
// short-circuit in the case of busted things.
// comments, etc.
if (this.comment) return false
if (this.empty) return f === ''
if (f === '/' && partial) return true
var options = this.options
// windows: need to use /, not \
if (path.sep !== '/') {
f = f.split(path.sep).join('/')
}
// treat the test path as a set of pathparts.
f = f.split(slashSplit)
this.debug(this.pattern, 'split', f)
// just ONE of the pattern sets in this.set needs to match
// in order for it to be valid. If negating, then just one
// match means that we have failed.
// Either way, return on the first hit.
var set = this.set
this.debug(this.pattern, 'set', set)
// Find the basename of the path by looking for the last non-empty segment
var filename
var i
for (i = f.length - 1; i >= 0; i--) {
filename = f[i]
if (filename) break
}
for (i = 0; i < set.length; i++) {
var pattern = set[i]
var file = f
if (options.matchBase && pattern.length === 1) {
file = [filename]
}
var hit = this.matchOne(file, pattern, partial)
if (hit) {
if (options.flipNegate) return true
return !this.negate
}
}
// didn't get any hits. this is success if it's a negative
// pattern, failure otherwise.
if (options.flipNegate) return false
return this.negate
}
// set partial to true to test if, for example,
// "/a/b" matches the start of "/*/b/*/d"
// Partial means, if you run out of file before you run
// out of pattern, then that's fine, as long as all
// the parts match.
Minimatch.prototype.matchOne = function (file, pattern, partial) {
var options = this.options
this.debug('matchOne',
{ 'this': this, file: file, pattern: pattern })
this.debug('matchOne', file.length, pattern.length)
for (var fi = 0,
pi = 0,
fl = file.length,
pl = pattern.length
; (fi < fl) && (pi < pl)
; fi++, pi++) {
this.debug('matchOne loop')
var p = pattern[pi]
var f = file[fi]
this.debug(pattern, p, f)
// should be impossible.
// some invalid regexp stuff in the set.
if (p === false) return false
if (p === GLOBSTAR) {
this.debug('GLOBSTAR', [pattern, p, f])
// "**"
// a/**/b/**/c would match the following:
// a/b/x/y/z/c
// a/x/y/z/b/c
// a/b/x/b/x/c
// a/b/c
// To do this, take the rest of the pattern after
// the **, and see if it would match the file remainder.
// If so, return success.
// If not, the ** "swallows" a segment, and try again.
// This is recursively awful.
//
// a/**/b/**/c matching a/b/x/y/z/c
// - a matches a
// - doublestar
// - matchOne(b/x/y/z/c, b/**/c)
// - b matches b
// - doublestar
// - matchOne(x/y/z/c, c) -> no
// - matchOne(y/z/c, c) -> no
// - matchOne(z/c, c) -> no
// - matchOne(c, c) yes, hit
var fr = fi
var pr = pi + 1
if (pr === pl) {
this.debug('** at the end')
// a ** at the end will just swallow the rest.
// We have found a match.
// however, it will not swallow /.x, unless
// options.dot is set.
// . and .. are *never* matched by **, for explosively
// exponential reasons.
for (; fi < fl; fi++) {
if (file[fi] === '.' || file[fi] === '..' ||
(!options.dot && file[fi].charAt(0) === '.')) return false
}
return true
}
// ok, let's see if we can swallow whatever we can.
while (fr < fl) {
var swallowee = file[fr]
this.debug('\nglobstar while', file, fr, pattern, pr, swallowee)
// XXX remove this slice. Just pass the start index.
if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
this.debug('globstar found match!', fr, fl, swallowee)
// found a match.
return true
} else {
// can't swallow "." or ".." ever.
// can only swallow ".foo" when explicitly asked.
if (swallowee === '.' || swallowee === '..' ||
(!options.dot && swallowee.charAt(0) === '.')) {
this.debug('dot detected!', file, fr, pattern, pr)
break
}
// ** swallows a segment, and continue.
this.debug('globstar swallow a segment, and continue')
fr++
}
}
// no match was found.
// However, in partial mode, we can't say this is necessarily over.
// If there's more *pattern* left, then
if (partial) {
// ran out of file
this.debug('\n>>> no match, partial?', file, fr, pattern, pr)
if (fr === fl) return true
}
return false
}
// something other than **
// non-magic patterns just have to match exactly
// patterns with magic have been turned into regexps.
var hit
if (typeof p === 'string') {
if (options.nocase) {
hit = f.toLowerCase() === p.toLowerCase()
} else {
hit = f === p
}
this.debug('string match', p, f, hit)
} else {
hit = f.match(p)
this.debug('pattern match', p, f, hit)
}
if (!hit) return false
}
// Note: ending in / means that we'll get a final ""
// at the end of the pattern. This can only match a
// corresponding "" at the end of the file.
// If the file ends in /, then it can only match a
// a pattern that ends in /, unless the pattern just
// doesn't have any more for it. But, a/b/ should *not*
// match "a/b/*", even though "" matches against the
// [^/]*? pattern, except in partial mode, where it might
// simply not be reached yet.
// However, a/b/ should still satisfy a/*
// now either we fell off the end of the pattern, or we're done.
if (fi === fl && pi === pl) {
// ran out of pattern and filename at the same time.
// an exact hit!
return true
} else if (fi === fl) {
// ran out of file, but still had pattern left.
// this is ok if we're doing the match as part of
// a glob fs traversal.
return partial
} else if (pi === pl) {
// ran out of pattern, still have file left.
// this is only acceptable if we're on the very last
// empty segment of a file with a trailing slash.
// a/* should match a/b/
var emptyFileEnd = (fi === fl - 1) && (file[fi] === '')
return emptyFileEnd
}
// should be unreachable.
throw new Error('wtf?')
}
// replace stuff like \* with *
function globUnescape (s) {
return s.replace(/\\(.)/g, '$1')
}
function regExpEscape (s) {
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 10.34% | (6 / 58) | 0% | (0 / 42) | 0% | (0 / 6) | 11.32% | (6 / 53) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 1 1 1 1 1 1 | var path = require('path');
var fs = require('fs');
var _0777 = parseInt('0777', 8);
module.exports = mkdirP.mkdirp = mkdirP.mkdirP = mkdirP;
function mkdirP (p, opts, f, made) {
if (typeof opts === 'function') {
f = opts;
opts = {};
}
else if (!opts || typeof opts !== 'object') {
opts = { mode: opts };
}
var mode = opts.mode;
var xfs = opts.fs || fs;
if (mode === undefined) {
mode = _0777 & (~process.umask());
}
if (!made) made = null;
var cb = f || function () {};
p = path.resolve(p);
xfs.mkdir(p, mode, function (er) {
if (!er) {
made = made || p;
return cb(null, made);
}
switch (er.code) {
case 'ENOENT':
mkdirP(path.dirname(p), opts, function (er, made) {
if (er) cb(er, made);
else mkdirP(p, opts, cb, made);
});
break;
// In the case of any other error, just see if there's a dir
// there already. If so, then hooray! If not, then something
// is borked.
default:
xfs.stat(p, function (er2, stat) {
// if the stat fails, then that's super weird.
// let the original error be the failure reason.
if (er2 || !stat.isDirectory()) cb(er, made)
else cb(null, made);
});
break;
}
});
}
mkdirP.sync = function sync (p, opts, made) {
if (!opts || typeof opts !== 'object') {
opts = { mode: opts };
}
var mode = opts.mode;
var xfs = opts.fs || fs;
if (mode === undefined) {
mode = _0777 & (~process.umask());
}
if (!made) made = null;
p = path.resolve(p);
try {
xfs.mkdirSync(p, mode);
made = made || p;
}
catch (err0) {
switch (err0.code) {
case 'ENOENT' :
made = sync(path.dirname(p), opts, made);
sync(p, opts, made);
break;
// In the case of any other error, just see if there's a dir
// there already. If so, then hooray! If not, then something
// is borked.
default:
var stat;
try {
stat = xfs.statSync(p);
}
catch (err1) {
throw err0;
}
if (!stat.isDirectory()) throw err0;
break;
}
}
return made;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| extract_description.js | 18.18% | (2 / 11) | 0% | (0 / 8) | 0% | (0 / 1) | 22.22% | (2 / 9) | |
| fixer.js | 6.88% | (19 / 276) | 0% | (0 / 241) | 0% | (0 / 42) | 7.6% | (19 / 250) | |
| make_warning.js | 26.67% | (4 / 15) | 0% | (0 / 6) | 0% | (0 / 2) | 26.67% | (4 / 15) | |
| normalize.js | 48% | (12 / 25) | 0% | (0 / 13) | 33.33% | (2 / 6) | 57.14% | (12 / 21) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 1 1 | module.exports = extractDescription // Extracts description from contents of a readme file in markdown format function extractDescription (d) { if (!d) return; if (d === "ERROR: No README data found!") return; // the first block of text before the first heading // that isn't the first line heading d = d.trim().split('\n') for (var s = 0; d[s] && d[s].trim().match(/^(#|$)/); s ++); var l = d.length for (var e = s + 1; e < l && d[e].trim(); e ++); return d.slice(s, e).join(' ').trim() } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | var semver = require("semver")
var validateLicense = require('validate-npm-package-license');
var hostedGitInfo = require("hosted-git-info")
var isBuiltinModule = require("is-builtin-module")
var depTypes = ["dependencies","devDependencies","optionalDependencies"]
var extractDescription = require("./extract_description")
var url = require("url")
var typos = require("./typos")
var fixer = module.exports = {
// default warning function
warn: function() {},
fixRepositoryField: function(data) {
if (data.repositories) {
this.warn("repositories");
data.repository = data.repositories[0]
}
if (!data.repository) return this.warn("missingRepository")
if (typeof data.repository === "string") {
data.repository = {
type: "git",
url: data.repository
}
}
var r = data.repository.url || ""
if (r) {
var hosted = hostedGitInfo.fromUrl(r)
if (hosted) {
r = data.repository.url
= hosted.getDefaultRepresentation() == "shortcut" ? hosted.https() : hosted.toString()
}
}
if (r.match(/github.com\/[^\/]+\/[^\/]+\.git\.git$/)) {
this.warn("brokenGitUrl", r)
}
}
, fixTypos: function(data) {
Object.keys(typos.topLevel).forEach(function (d) {
if (data.hasOwnProperty(d)) {
this.warn("typo", d, typos.topLevel[d])
}
}, this)
}
, fixScriptsField: function(data) {
if (!data.scripts) return
if (typeof data.scripts !== "object") {
this.warn("nonObjectScripts")
delete data.scripts
return
}
Object.keys(data.scripts).forEach(function (k) {
if (typeof data.scripts[k] !== "string") {
this.warn("nonStringScript")
delete data.scripts[k]
} else if (typos.script[k] && !data.scripts[typos.script[k]]) {
this.warn("typo", k, typos.script[k], "scripts")
}
}, this)
}
, fixFilesField: function(data) {
var files = data.files
if (files && !Array.isArray(files)) {
this.warn("nonArrayFiles")
delete data.files
} else if (data.files) {
data.files = data.files.filter(function(file) {
if (!file || typeof file !== "string") {
this.warn("invalidFilename", file)
return false
} else {
return true
}
}, this)
}
}
, fixBinField: function(data) {
if (!data.bin) return;
if (typeof data.bin === "string") {
var b = {}
var match
if (match = data.name.match(/^@[^/]+[/](.*)$/)) {
b[match[1]] = data.bin
} else {
b[data.name] = data.bin
}
data.bin = b
}
}
, fixManField: function(data) {
if (!data.man) return;
if (typeof data.man === "string") {
data.man = [ data.man ]
}
}
, fixBundleDependenciesField: function(data) {
var bdd = "bundledDependencies"
var bd = "bundleDependencies"
if (data[bdd] && !data[bd]) {
data[bd] = data[bdd]
delete data[bdd]
}
if (data[bd] && !Array.isArray(data[bd])) {
this.warn("nonArrayBundleDependencies")
delete data[bd]
} else if (data[bd]) {
data[bd] = data[bd].filter(function(bd) {
if (!bd || typeof bd !== 'string') {
this.warn("nonStringBundleDependency", bd)
return false
} else {
if (!data.dependencies) {
data.dependencies = {}
}
if (!data.dependencies.hasOwnProperty(bd)) {
this.warn("nonDependencyBundleDependency", bd)
data.dependencies[bd] = "*"
}
return true
}
}, this)
}
}
, fixDependencies: function(data, strict) {
var loose = !strict
objectifyDeps(data, this.warn)
addOptionalDepsToDeps(data, this.warn)
this.fixBundleDependenciesField(data)
;['dependencies','devDependencies'].forEach(function(deps) {
if (!(deps in data)) return
if (!data[deps] || typeof data[deps] !== "object") {
this.warn("nonObjectDependencies", deps)
delete data[deps]
return
}
Object.keys(data[deps]).forEach(function (d) {
var r = data[deps][d]
if (typeof r !== 'string') {
this.warn("nonStringDependency", d, JSON.stringify(r))
delete data[deps][d]
}
var hosted = hostedGitInfo.fromUrl(data[deps][d])
if (hosted) data[deps][d] = hosted.toString()
}, this)
}, this)
}
, fixModulesField: function (data) {
if (data.modules) {
this.warn("deprecatedModules")
delete data.modules
}
}
, fixKeywordsField: function (data) {
if (typeof data.keywords === "string") {
data.keywords = data.keywords.split(/,\s+/)
}
if (data.keywords && !Array.isArray(data.keywords)) {
delete data.keywords
this.warn("nonArrayKeywords")
} else if (data.keywords) {
data.keywords = data.keywords.filter(function(kw) {
if (typeof kw !== "string" || !kw) {
this.warn("nonStringKeyword");
return false
} else {
return true
}
}, this)
}
}
, fixVersionField: function(data, strict) {
// allow "loose" semver 1.0 versions in non-strict mode
// enforce strict semver 2.0 compliance in strict mode
var loose = !strict
if (!data.version) {
data.version = ""
return true
}
if (!semver.valid(data.version, loose)) {
throw new Error('Invalid version: "'+ data.version + '"')
}
data.version = semver.clean(data.version, loose)
return true
}
, fixPeople: function(data) {
modifyPeople(data, unParsePerson)
modifyPeople(data, parsePerson)
}
, fixNameField: function(data, options) {
if (typeof options === "boolean") options = {strict: options}
else if (typeof options === "undefined") options = {}
var strict = options.strict
if (!data.name && !strict) {
data.name = ""
return
}
if (typeof data.name !== "string") {
throw new Error("name field must be a string.")
}
if (!strict)
data.name = data.name.trim()
ensureValidName(data.name, strict, options.allowLegacyCase)
if (isBuiltinModule(data.name))
this.warn("conflictingName", data.name)
}
, fixDescriptionField: function (data) {
if (data.description && typeof data.description !== 'string') {
this.warn("nonStringDescription")
delete data.description
}
if (data.readme && !data.description)
data.description = extractDescription(data.readme)
if(data.description === undefined) delete data.description;
if (!data.description) this.warn("missingDescription")
}
, fixReadmeField: function (data) {
if (!data.readme) {
this.warn("missingReadme")
data.readme = "ERROR: No README data found!"
}
}
, fixBugsField: function(data) {
if (!data.bugs && data.repository && data.repository.url) {
var hosted = hostedGitInfo.fromUrl(data.repository.url)
if(hosted && hosted.bugs()) {
data.bugs = {url: hosted.bugs()}
}
}
else if(data.bugs) {
var emailRe = /^.+@.*\..+$/
if(typeof data.bugs == "string") {
if(emailRe.test(data.bugs))
data.bugs = {email:data.bugs}
else if(url.parse(data.bugs).protocol)
data.bugs = {url: data.bugs}
else
this.warn("nonEmailUrlBugsString")
}
else {
bugsTypos(data.bugs, this.warn)
var oldBugs = data.bugs
data.bugs = {}
if(oldBugs.url) {
if(typeof(oldBugs.url) == "string" && url.parse(oldBugs.url).protocol)
data.bugs.url = oldBugs.url
else
this.warn("nonUrlBugsUrlField")
}
if(oldBugs.email) {
if(typeof(oldBugs.email) == "string" && emailRe.test(oldBugs.email))
data.bugs.email = oldBugs.email
else
this.warn("nonEmailBugsEmailField")
}
}
if(!data.bugs.email && !data.bugs.url) {
delete data.bugs
this.warn("emptyNormalizedBugs")
}
}
}
, fixHomepageField: function(data) {
if (!data.homepage && data.repository && data.repository.url) {
var hosted = hostedGitInfo.fromUrl(data.repository.url)
if (hosted && hosted.docs()) data.homepage = hosted.docs()
}
if (!data.homepage) return
if(typeof data.homepage !== "string") {
this.warn("nonUrlHomepage")
return delete data.homepage
}
if(!url.parse(data.homepage).protocol) {
this.warn("missingProtocolHomepage")
data.homepage = "http://" + data.homepage
}
}
, fixLicenseField: function(data) {
if (!data.license) {
return this.warn("missingLicense")
} else{
if (
typeof(data.license) !== 'string' ||
data.license.length < 1
) {
this.warn("invalidLicense")
} else {
if (!validateLicense(data.license).validForNewPackages)
this.warn("invalidLicense")
}
}
}
}
function isValidScopedPackageName(spec) {
if (spec.charAt(0) !== '@') return false
var rest = spec.slice(1).split('/')
if (rest.length !== 2) return false
return rest[0] && rest[1] &&
rest[0] === encodeURIComponent(rest[0]) &&
rest[1] === encodeURIComponent(rest[1])
}
function isCorrectlyEncodedName(spec) {
return !spec.match(/[\/@\s\+%:]/) &&
spec === encodeURIComponent(spec)
}
function ensureValidName (name, strict, allowLegacyCase) {
if (name.charAt(0) === "." ||
!(isValidScopedPackageName(name) || isCorrectlyEncodedName(name)) ||
(strict && (!allowLegacyCase) && name !== name.toLowerCase()) ||
name.toLowerCase() === "node_modules" ||
name.toLowerCase() === "favicon.ico") {
throw new Error("Invalid name: " + JSON.stringify(name))
}
}
function modifyPeople (data, fn) {
if (data.author) data.author = fn(data.author)
;["maintainers", "contributors"].forEach(function (set) {
if (!Array.isArray(data[set])) return;
data[set] = data[set].map(fn)
})
return data
}
function unParsePerson (person) {
if (typeof person === "string") return person
var name = person.name || ""
var u = person.url || person.web
var url = u ? (" ("+u+")") : ""
var e = person.email || person.mail
var email = e ? (" <"+e+">") : ""
return name+email+url
}
function parsePerson (person) {
if (typeof person !== "string") return person
var name = person.match(/^([^\(<]+)/)
var url = person.match(/\(([^\)]+)\)/)
var email = person.match(/<([^>]+)>/)
var obj = {}
if (name && name[0].trim()) obj.name = name[0].trim()
if (email) obj.email = email[1];
if (url) obj.url = url[1];
return obj
}
function addOptionalDepsToDeps (data, warn) {
var o = data.optionalDependencies
if (!o) return;
var d = data.dependencies || {}
Object.keys(o).forEach(function (k) {
d[k] = o[k]
})
data.dependencies = d
}
function depObjectify (deps, type, warn) {
if (!deps) return {}
if (typeof deps === "string") {
deps = deps.trim().split(/[\n\r\s\t ,]+/)
}
if (!Array.isArray(deps)) return deps
warn("deprecatedArrayDependencies", type)
var o = {}
deps.filter(function (d) {
return typeof d === "string"
}).forEach(function(d) {
d = d.trim().split(/(:?[@\s><=])/)
var dn = d.shift()
var dv = d.join("")
dv = dv.trim()
dv = dv.replace(/^@/, "")
o[dn] = dv
})
return o
}
function objectifyDeps (data, warn) {
depTypes.forEach(function (type) {
if (!data[type]) return;
data[type] = depObjectify(data[type], type, warn)
})
}
function bugsTypos(bugs, warn) {
if (!bugs) return
Object.keys(bugs).forEach(function (k) {
if (typos.bugs[k]) {
warn("typo", k, typos.bugs[k], "bugs")
bugs[typos.bugs[k]] = bugs[k]
delete bugs[k]
}
})
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 1 1 1 1 | var util = require("util")
var messages = require("./warning_messages.json")
module.exports = function() {
var args = Array.prototype.slice.call(arguments, 0)
var warningName = args.shift()
if (warningName == "typo") {
return makeTypoWarning.apply(null,args)
}
else {
var msgTemplate = messages[warningName] ? messages[warningName] : warningName + ": '%s'"
args.unshift(msgTemplate)
return util.format.apply(null, args)
}
}
function makeTypoWarning (providedName, probableName, field) {
if (field) {
providedName = field + "['" + providedName + "']"
probableName = field + "['" + probableName + "']"
}
return util.format(messages.typo, providedName, probableName)
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | 1 1 1 1 1 1 1 14 1 1 1 14 | module.exports = normalize
var fixer = require("./fixer")
normalize.fixer = fixer
var makeWarning = require("./make_warning")
var fieldsToFix = ['name','version','description','repository','modules','scripts'
,'files','bin','man','bugs','keywords','readme','homepage','license']
var otherThingsToFix = ['dependencies','people', 'typos']
var thingsToFix = fieldsToFix.map(function(fieldName) {
return ucFirst(fieldName) + "Field"
})
// two ways to do this in CoffeeScript on only one line, sub-70 chars:
// thingsToFix = fieldsToFix.map (name) -> ucFirst(name) + "Field"
// thingsToFix = (ucFirst(name) + "Field" for name in fieldsToFix)
thingsToFix = thingsToFix.concat(otherThingsToFix)
function normalize (data, warn, strict) {
if(warn === true) warn = null, strict = true
if(!strict) strict = false
if(!warn || data.private) warn = function(msg) { /* noop */ }
if (data.scripts &&
data.scripts.install === "node-gyp rebuild" &&
!data.scripts.preinstall) {
data.gypfile = true
}
fixer.warn = function() { warn(makeWarning.apply(null, arguments)) }
thingsToFix.forEach(function(thingName) {
fixer["fix" + ucFirst(thingName)](data, strict)
})
data._id = data.name + "@" + data.version
}
function ucFirst (string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 14.29% | (1 / 7) | 0% | (0 / 4) | 0% | (0 / 1) | 14.29% | (1 / 7) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 1 | /*! * normalize-path <https://github.com/jonschlinkert/normalize-path> * * Copyright (c) 2014-2015, Jon Schlinkert. * Licensed under the MIT License */ module.exports = function normalizePath(str, stripTrailing) { if (typeof str !== 'string') { throw new TypeError('expected a string'); } str = str.replace(/[\\\/]+/g, '/'); if (stripTrailing !== false) { str = str.replace(/\/$/, ''); } return str; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (22 / 44) | 25% | (5 / 20) | 60% | (3 / 5) | 50% | (22 / 44) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 1 1 1 1 1 1 1 1 1 1 1 1 10 1 10 1 1 1 20 1 1 1 | /* object-assign (c) Sindre Sorhus @license MIT */ 'use strict'; /* eslint-disable no-unused-vars */ var getOwnPropertySymbols = Object.getOwnPropertySymbols; var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(val) { if (val === null || val === undefined) { throw new TypeError('Object.assign cannot be called with null or undefined'); } return Object(val); } function shouldUseNative() { try { Iif (!Object.assign) { return false; } // Detect buggy property enumeration order in older V8 versions. // https://bugs.chromium.org/p/v8/issues/detail?id=4118 var test1 = new String('abc'); // eslint-disable-line no-new-wrappers test1[5] = 'de'; Iif (Object.getOwnPropertyNames(test1)[0] === '5') { return false; } // https://bugs.chromium.org/p/v8/issues/detail?id=3056 var test2 = {}; for (var i = 0; i < 10; i++) { test2['_' + String.fromCharCode(i)] = i; } var order2 = Object.getOwnPropertyNames(test2).map(function (n) { return test2[n]; }); Iif (order2.join('') !== '0123456789') { return false; } // https://bugs.chromium.org/p/v8/issues/detail?id=3056 var test3 = {}; 'abcdefghijklmnopqrst'.split('').forEach(function (letter) { test3[letter] = letter; }); Iif (Object.keys(Object.assign({}, test3)).join('') !== 'abcdefghijklmnopqrst') { return false; } return true; } catch (err) { // We don't expect any of the above to throw, but better to be safe. return false; } } module.exports = shouldUseNative() ? Object.assign : function (target, source) { var from; var to = toObject(target); var symbols; for (var s = 1; s < arguments.length; s++) { from = Object(arguments[s]); for (var key in from) { if (hasOwnProperty.call(from, key)) { to[key] = from[key]; } } if (getOwnPropertySymbols) { symbols = getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) { if (propIsEnumerable.call(from, symbols[i])) { to[symbols[i]] = from[symbols[i]]; } } } } return to; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 15% | (3 / 20) | 0% | (0 / 14) | 0% | (0 / 2) | 15.79% | (3 / 19) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 1 1 1 | /*!
* object.omit <https://github.com/jonschlinkert/object.omit>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var isObject = require('is-extendable');
var forOwn = require('for-own');
module.exports = function omit(obj, keys) {
if (!isObject(obj)) return {};
keys = [].concat.apply([], [].slice.call(arguments, 1));
var last = keys[keys.length - 1];
var res = {}, fn;
if (typeof last === 'function') {
fn = keys.pop();
}
var isFunction = typeof fn === 'function';
if (!keys.length && !isFunction) {
return obj;
}
forOwn(obj, function(value, key) {
if (keys.indexOf(key) === -1) {
if (!isFunction) {
res[key] = value;
} else if (fn(value, key, obj)) {
res[key] = value;
}
}
});
return res;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| once.js | 34.62% | (9 / 26) | 0% | (0 / 6) | 14.29% | (1 / 7) | 36% | (9 / 25) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | 1 1 1 1 1 1 1 1 1 | var wrappy = require('wrappy')
module.exports = wrappy(once)
module.exports.strict = wrappy(onceStrict)
once.proto = once(function () {
Object.defineProperty(Function.prototype, 'once', {
value: function () {
return once(this)
},
configurable: true
})
Object.defineProperty(Function.prototype, 'onceStrict', {
value: function () {
return onceStrict(this)
},
configurable: true
})
})
function once (fn) {
var f = function () {
if (f.called) return f.value
f.called = true
return f.value = fn.apply(this, arguments)
}
f.called = false
return f
}
function onceStrict (fn) {
var f = function () {
if (f.called)
throw new Error(f.onceError)
f.called = true
return f.value = fn.apply(this, arguments)
}
var name = fn.name || 'Function wrapped with `once`'
f.onceError = name + " shouldn't be called more than once"
f.called = false
return f
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 14.47% | (11 / 76) | 0% | (0 / 49) | 0% | (0 / 7) | 14.67% | (11 / 75) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | 1 1 1 1 1 1 1 1 1 1 1 | /*!
* parse-glob <https://github.com/jonschlinkert/parse-glob>
*
* Copyright (c) 2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
var isGlob = require('is-glob');
var findBase = require('glob-base');
var extglob = require('is-extglob');
var dotfile = require('is-dotfile');
/**
* Expose `cache`
*/
var cache = module.exports.cache = {};
/**
* Parse a glob pattern into tokens.
*
* When no paths or '**' are in the glob, we use a
* different strategy for parsing the filename, since
* file names can contain braces and other difficult
* patterns. such as:
*
* - `*.{a,b}`
* - `(**|*.js)`
*/
module.exports = function parseGlob(glob) {
if (cache.hasOwnProperty(glob)) {
return cache[glob];
}
var tok = {};
tok.orig = glob;
tok.is = {};
// unescape dots and slashes in braces/brackets
glob = escape(glob);
var parsed = findBase(glob);
tok.is.glob = parsed.isGlob;
tok.glob = parsed.glob;
tok.base = parsed.base;
var segs = /([^\/]*)$/.exec(glob);
tok.path = {};
tok.path.dirname = '';
tok.path.basename = segs[1] || '';
tok.path.dirname = glob.split(tok.path.basename).join('') || '';
var basename = (tok.path.basename || '').split('.') || '';
tok.path.filename = basename[0] || '';
tok.path.extname = basename.slice(1).join('.') || '';
tok.path.ext = '';
if (isGlob(tok.path.dirname) && !tok.path.basename) {
if (!/\/$/.test(tok.glob)) {
tok.path.basename = tok.glob;
}
tok.path.dirname = tok.base;
}
if (glob.indexOf('/') === -1 && !tok.is.globstar) {
tok.path.dirname = '';
tok.path.basename = tok.orig;
}
var dot = tok.path.basename.indexOf('.');
if (dot !== -1) {
tok.path.filename = tok.path.basename.slice(0, dot);
tok.path.extname = tok.path.basename.slice(dot);
}
if (tok.path.extname.charAt(0) === '.') {
var exts = tok.path.extname.split('.');
tok.path.ext = exts[exts.length - 1];
}
// unescape dots and slashes in braces/brackets
tok.glob = unescape(tok.glob);
tok.path.dirname = unescape(tok.path.dirname);
tok.path.basename = unescape(tok.path.basename);
tok.path.filename = unescape(tok.path.filename);
tok.path.extname = unescape(tok.path.extname);
// Booleans
var is = (glob && tok.is.glob);
tok.is.negated = glob && glob.charAt(0) === '!';
tok.is.extglob = glob && extglob(glob);
tok.is.braces = has(is, glob, '{');
tok.is.brackets = has(is, glob, '[:');
tok.is.globstar = has(is, glob, '**');
tok.is.dotfile = dotfile(tok.path.basename) || dotfile(tok.path.filename);
tok.is.dotdir = dotdir(tok.path.dirname);
return (cache[glob] = tok);
}
/**
* Returns true if the glob matches dot-directories.
*
* @param {Object} `tok` The tokens object
* @param {Object} `path` The path object
* @return {Object}
*/
function dotdir(base) {
if (base.indexOf('/.') !== -1) {
return true;
}
if (base.charAt(0) === '.' && base.charAt(1) !== '/') {
return true;
}
return false;
}
/**
* Returns true if the pattern has the given `ch`aracter(s)
*
* @param {Object} `glob` The glob pattern.
* @param {Object} `ch` The character to test for
* @return {Object}
*/
function has(is, glob, ch) {
return is && glob.indexOf(ch) !== -1;
}
/**
* Escape/unescape utils
*/
function escape(str) {
var re = /\{([^{}]*?)}|\(([^()]*?)\)|\[([^\[\]]*?)\]/g;
return str.replace(re, function (outter, braces, parens, brackets) {
var inner = braces || parens || brackets;
if (!inner) { return outter; }
return outter.split(inner).join(esc(inner));
});
}
function esc(str) {
str = str.split('/').join('__SLASH__');
str = str.split('.').join('__DOT__');
return str;
}
function unescape(str) {
str = str.split('__SLASH__').join('/');
str = str.split('__DOT__').join('.');
return str;
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 25% | (4 / 16) | 0% | (0 / 4) | 0% | (0 / 1) | 25% | (4 / 16) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 1 1 1 1 | 'use strict';
var errorEx = require('error-ex');
var fallback = require('./vendor/parse');
var JSONError = errorEx('JSONError', {
fileName: errorEx.append('in %s')
});
module.exports = function (x, reviver, filename) {
if (typeof reviver === 'string') {
filename = reviver;
reviver = null;
}
try {
try {
return JSON.parse(x, reviver);
} catch (err) {
fallback.parse(x, {
mode: 'json',
reviver: reviver
});
throw err;
}
} catch (err) {
var jsonErr = new JSONError(err);
if (filename) {
jsonErr.fileName = filename;
}
throw jsonErr;
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| parse.js | 5.34% | (21 / 393) | 0% | (0 / 335) | 0% | (0 / 26) | 5.65% | (21 / 372) | |
| unicode.js | 60% | (9 / 15) | 0% | (0 / 42) | 0% | (0 / 6) | 60% | (9 / 15) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /*
* Author: Alex Kocharin <alex@kocharin.ru>
* GIT: https://github.com/rlidwka/jju
* License: WTFPL, grab your copy here: http://www.wtfpl.net/txt/copying/
*/
// RTFM: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
var Uni = require('./unicode')
function isHexDigit(x) {
return (x >= '0' && x <= '9')
|| (x >= 'A' && x <= 'F')
|| (x >= 'a' && x <= 'f')
}
function isOctDigit(x) {
return x >= '0' && x <= '7'
}
function isDecDigit(x) {
return x >= '0' && x <= '9'
}
var unescapeMap = {
'\'': '\'',
'"' : '"',
'\\': '\\',
'b' : '\b',
'f' : '\f',
'n' : '\n',
'r' : '\r',
't' : '\t',
'v' : '\v',
'/' : '/',
}
function formatError(input, msg, position, lineno, column, json5) {
var result = msg + ' at ' + (lineno + 1) + ':' + (column + 1)
, tmppos = position - column - 1
, srcline = ''
, underline = ''
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
// output no more than 70 characters before the wrong ones
if (tmppos < position - 70) {
tmppos = position - 70
}
while (1) {
var chr = input[++tmppos]
if (isLineTerminator(chr) || tmppos === input.length) {
if (position >= tmppos) {
// ending line error, so show it after the last char
underline += '^'
}
break
}
srcline += chr
if (position === tmppos) {
underline += '^'
} else if (position > tmppos) {
underline += input[tmppos] === '\t' ? '\t' : ' '
}
// output no more than 78 characters on the string
if (srcline.length > 78) break
}
return result + '\n' + srcline + '\n' + underline
}
function parse(input, options) {
// parse as a standard JSON mode
var json5 = !(options.mode === 'json' || options.legacy)
var isLineTerminator = json5 ? Uni.isLineTerminator : Uni.isLineTerminatorJSON
var isWhiteSpace = json5 ? Uni.isWhiteSpace : Uni.isWhiteSpaceJSON
var length = input.length
, lineno = 0
, linestart = 0
, position = 0
, stack = []
var tokenStart = function() {}
var tokenEnd = function(v) {return v}
/* tokenize({
raw: '...',
type: 'whitespace'|'comment'|'key'|'literal'|'separator'|'newline',
value: 'number'|'string'|'whatever',
path: [...],
})
*/
if (options._tokenize) {
;(function() {
var start = null
tokenStart = function() {
if (start !== null) throw Error('internal error, token overlap')
start = position
}
tokenEnd = function(v, type) {
if (start != position) {
var hash = {
raw: input.substr(start, position-start),
type: type,
stack: stack.slice(0),
}
if (v !== undefined) hash.value = v
options._tokenize.call(null, hash)
}
start = null
return v
}
})()
}
function fail(msg) {
var column = position - linestart
if (!msg) {
if (position < length) {
var token = '\'' +
JSON
.stringify(input[position])
.replace(/^"|"$/g, '')
.replace(/'/g, "\\'")
.replace(/\\"/g, '"')
+ '\''
if (!msg) msg = 'Unexpected token ' + token
} else {
if (!msg) msg = 'Unexpected end of input'
}
}
var error = SyntaxError(formatError(input, msg, position, lineno, column, json5))
error.row = lineno + 1
error.column = column + 1
throw error
}
function newline(chr) {
// account for <cr><lf>
if (chr === '\r' && input[position] === '\n') position++
linestart = position
lineno++
}
function parseGeneric() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'literal')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '-'
|| chr === '.'
|| isDecDigit(chr)
// + number Infinity NaN
|| (json5 && (chr === '+' || chr === 'I' || chr === 'N'))
) {
return tokenEnd(parseNumber(), 'literal')
} else if (chr === 'n') {
parseKeyword('null')
return tokenEnd(null, 'literal')
} else if (chr === 't') {
parseKeyword('true')
return tokenEnd(true, 'literal')
} else if (chr === 'f') {
parseKeyword('false')
return tokenEnd(false, 'literal')
} else {
position--
return tokenEnd(undefined)
}
}
}
function parseKey() {
var result
while (position < length) {
tokenStart()
var chr = input[position++]
if (chr === '"' || (chr === '\'' && json5)) {
return tokenEnd(parseString(chr), 'key')
} else if (chr === '{') {
tokenEnd(undefined, 'separator')
return parseObject()
} else if (chr === '[') {
tokenEnd(undefined, 'separator')
return parseArray()
} else if (chr === '.'
|| isDecDigit(chr)
) {
return tokenEnd(parseNumber(true), 'key')
} else if (json5
&& Uni.isIdentifierStart(chr) || (chr === '\\' && input[position] === 'u')) {
// unicode char or a unicode sequence
var rollback = position - 1
var result = parseIdentifier()
if (result === undefined) {
position = rollback
return tokenEnd(undefined)
} else {
return tokenEnd(result, 'key')
}
} else {
position--
return tokenEnd(undefined)
}
}
}
function skipWhiteSpace() {
tokenStart()
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
newline(chr)
tokenEnd(undefined, 'newline')
tokenStart()
} else if (isWhiteSpace(chr)) {
// nothing
} else if (chr === '/'
&& json5
&& (input[position] === '/' || input[position] === '*')
) {
position--
tokenEnd(undefined, 'whitespace')
tokenStart()
position++
skipComment(input[position++] === '*')
tokenEnd(undefined, 'comment')
tokenStart()
} else {
position--
break
}
}
return tokenEnd(undefined, 'whitespace')
}
function skipComment(multi) {
while (position < length) {
var chr = input[position++]
if (isLineTerminator(chr)) {
// LineTerminator is an end of singleline comment
if (!multi) {
// let parent function deal with newline
position--
return
}
newline(chr)
} else if (chr === '*' && multi) {
// end of multiline comment
if (input[position] === '/') {
position++
return
}
} else {
// nothing
}
}
if (multi) {
fail('Unclosed multiline comment')
}
}
function parseKeyword(keyword) {
// keyword[0] is not checked because it should've checked earlier
var _pos = position
var len = keyword.length
for (var i=1; i<len; i++) {
if (position >= length || keyword[i] != input[position]) {
position = _pos-1
fail()
}
position++
}
}
function parseObject() {
var result = options.null_prototype ? Object.create(null) : {}
, empty_object = {}
, is_non_empty = false
while (position < length) {
skipWhiteSpace()
var item1 = parseKey()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === '}' && item1 === undefined) {
if (!json5 && is_non_empty) {
position--
fail('Trailing comma in object')
}
return result
} else if (chr === ':' && item1 !== undefined) {
skipWhiteSpace()
stack.push(item1)
var item2 = parseGeneric()
stack.pop()
if (item2 === undefined) fail('No value found for key ' + item1)
if (typeof(item1) !== 'string') {
if (!json5 || typeof(item1) !== 'number') {
fail('Wrong key type: ' + item1)
}
}
if ((item1 in empty_object || empty_object[item1] != null) && options.reserved_keys !== 'replace') {
if (options.reserved_keys === 'throw') {
fail('Reserved key: ' + item1)
} else {
// silently ignore it
}
} else {
if (typeof(options.reviver) === 'function') {
item2 = options.reviver.call(null, item1, item2)
}
if (item2 !== undefined) {
is_non_empty = true
Object.defineProperty(result, item1, {
value: item2,
enumerable: true,
configurable: true,
writable: true,
})
}
}
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (chr === ',') {
continue
} else if (chr === '}') {
return result
} else {
fail()
}
} else {
position--
fail()
}
}
fail()
}
function parseArray() {
var result = []
while (position < length) {
skipWhiteSpace()
stack.push(result.length)
var item = parseGeneric()
stack.pop()
skipWhiteSpace()
tokenStart()
var chr = input[position++]
tokenEnd(undefined, 'separator')
if (item !== undefined) {
if (typeof(options.reviver) === 'function') {
item = options.reviver.call(null, String(result.length), item)
}
if (item === undefined) {
result.length++
item = true // hack for check below, not included into result
} else {
result.push(item)
}
}
if (chr === ',') {
if (item === undefined) {
fail('Elisions are not supported')
}
} else if (chr === ']') {
if (!json5 && item === undefined && result.length) {
position--
fail('Trailing comma in array')
}
return result
} else {
position--
fail()
}
}
}
function parseNumber() {
// rewind because we don't know first char
position--
var start = position
, chr = input[position++]
, t
var to_num = function(is_octal) {
var str = input.substr(start, position - start)
if (is_octal) {
var result = parseInt(str.replace(/^0o?/, ''), 8)
} else {
var result = Number(str)
}
if (Number.isNaN(result)) {
position--
fail('Bad numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else if (!json5 && !str.match(/^-?(0|[1-9][0-9]*)(\.[0-9]+)?(e[+-]?[0-9]+)?$/i)) {
// additional restrictions imposed by json
position--
fail('Non-json numeric literal - "' + input.substr(start, position - start + 1) + '"')
} else {
return result
}
}
// ex: -5982475.249875e+29384
// ^ skipping this
if (chr === '-' || (chr === '+' && json5)) chr = input[position++]
if (chr === 'N' && json5) {
parseKeyword('NaN')
return NaN
}
if (chr === 'I' && json5) {
parseKeyword('Infinity')
// returning +inf or -inf
return to_num()
}
if (chr >= '1' && chr <= '9') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// special case for leading zero: 0.123456
if (chr === '0') {
chr = input[position++]
// new syntax, "0o777" old syntax, "0777"
var is_octal = chr === 'o' || chr === 'O' || isOctDigit(chr)
var is_hex = chr === 'x' || chr === 'X'
if (json5 && (is_octal || is_hex)) {
while (position < length
&& (is_hex ? isHexDigit : isOctDigit)( input[position] )
) position++
var sign = 1
if (input[start] === '-') {
sign = -1
start++
} else if (input[start] === '+') {
start++
}
return sign * to_num(is_octal)
}
}
if (chr === '.') {
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
if (chr === 'e' || chr === 'E') {
chr = input[position++]
if (chr === '-' || chr === '+') position++
// ex: -5982475.249875e+29384
// ^^^ skipping these
while (position < length && isDecDigit(input[position])) position++
chr = input[position++]
}
// we have char in the buffer, so count for it
position--
return to_num()
}
function parseIdentifier() {
// rewind because we don't know first char
position--
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === '\\'
&& input[position] === 'u'
&& isHexDigit(input[position+1])
&& isHexDigit(input[position+2])
&& isHexDigit(input[position+3])
&& isHexDigit(input[position+4])
) {
// UnicodeEscapeSequence
chr = String.fromCharCode(parseInt(input.substr(position+1, 4), 16))
position += 5
}
if (result.length) {
// identifier started
if (Uni.isIdentifierPart(chr)) {
result += chr
} else {
position--
return result
}
} else {
if (Uni.isIdentifierStart(chr)) {
result += chr
} else {
return undefined
}
}
}
fail()
}
function parseString(endChar) {
// 7.8.4 of ES262 spec
var result = ''
while (position < length) {
var chr = input[position++]
if (chr === endChar) {
return result
} else if (chr === '\\') {
if (position >= length) fail()
chr = input[position++]
if (unescapeMap[chr] && (json5 || (chr != 'v' && chr != "'"))) {
result += unescapeMap[chr]
} else if (json5 && isLineTerminator(chr)) {
// line continuation
newline(chr)
} else if (chr === 'u' || (chr === 'x' && json5)) {
// unicode/character escape sequence
var off = chr === 'u' ? 4 : 2
// validation for \uXXXX
for (var i=0; i<off; i++) {
if (position >= length) fail()
if (!isHexDigit(input[position])) fail('Bad escape sequence')
position++
}
result += String.fromCharCode(parseInt(input.substr(position-off, off), 16))
} else if (json5 && isOctDigit(chr)) {
if (chr < '4' && isOctDigit(input[position]) && isOctDigit(input[position+1])) {
// three-digit octal
var digits = 3
} else if (isOctDigit(input[position])) {
// two-digit octal
var digits = 2
} else {
var digits = 1
}
position += digits - 1
result += String.fromCharCode(parseInt(input.substr(position-digits, digits), 8))
/*if (!isOctDigit(input[position])) {
// \0 is allowed still
result += '\0'
} else {
fail('Octal literals are not supported')
}*/
} else if (json5) {
// \X -> x
result += chr
} else {
position--
fail()
}
} else if (isLineTerminator(chr)) {
fail()
} else {
if (!json5 && chr.charCodeAt(0) < 32) {
position--
fail('Unexpected control character')
}
// SourceCharacter but not one of " or \ or LineTerminator
result += chr
}
}
fail()
}
skipWhiteSpace()
var return_value = parseGeneric()
if (return_value !== undefined || position < length) {
skipWhiteSpace()
if (position >= length) {
if (typeof(options.reviver) === 'function') {
return_value = options.reviver.call(null, '', return_value)
}
return return_value
} else {
fail()
}
} else {
if (position) {
fail('No data, only a whitespace')
} else {
fail('No data, empty input')
}
}
}
/*
* parse(text, options)
* or
* parse(text, reviver)
*
* where:
* text - string
* options - object
* reviver - function
*/
module.exports.parse = function parseJSON(input, options) {
// support legacy functions
if (typeof(options) === 'function') {
options = {
reviver: options
}
}
if (input === undefined) {
// parse(stringify(x)) should be equal x
// with JSON functions it is not 'cause of undefined
// so we're fixing it
return undefined
}
// JSON.parse compat
if (typeof(input) !== 'string') input = String(input)
if (options == null) options = {}
if (options.reserved_keys == null) options.reserved_keys = 'ignore'
if (options.reserved_keys === 'throw' || options.reserved_keys === 'ignore') {
if (options.null_prototype == null) {
options.null_prototype = true
}
}
try {
return parse(input, options)
} catch(err) {
// jju is a recursive parser, so JSON.parse("{{{{{{{") could blow up the stack
//
// this catch is used to skip all those internal calls
if (err instanceof SyntaxError && err.row != null && err.column != null) {
var old_err = err
err = SyntaxError(old_err.message)
err.column = old_err.column
err.row = old_err.row
}
throw err
}
}
module.exports.tokenize = function tokenizeJSON(input, options) {
if (options == null) options = {}
options._tokenize = function(smth) {
if (options._addstack) smth.stack.unshift.apply(smth.stack, options._addstack)
tokens.push(smth)
}
var tokens = []
tokens.data = module.exports.parse(input, options)
return tokens
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 1 1 1 1 1 1 1 1 1 | // This is autogenerated with esprima tools, see: // https://github.com/ariya/esprima/blob/master/esprima.js // // PS: oh God, I hate Unicode // ECMAScript 5.1/Unicode v6.3.0 NonAsciiIdentifierStart: var Uni = module.exports module.exports.isWhiteSpace = function isWhiteSpace(x) { // section 7.2, table 2 return x === '\u0020' || x === '\u00A0' || x === '\uFEFF' // <-- this is not a Unicode WS, only a JS one || (x >= '\u0009' && x <= '\u000D') // 9 A B C D // + whitespace characters from unicode, category Zs || x === '\u1680' || x === '\u180E' || (x >= '\u2000' && x <= '\u200A') // 0 1 2 3 4 5 6 7 8 9 A || x === '\u2028' || x === '\u2029' || x === '\u202F' || x === '\u205F' || x === '\u3000' } module.exports.isWhiteSpaceJSON = function isWhiteSpaceJSON(x) { return x === '\u0020' || x === '\u0009' || x === '\u000A' || x === '\u000D' } module.exports.isLineTerminator = function isLineTerminator(x) { // ok, here is the part when JSON is wrong // section 7.3, table 3 return x === '\u000A' || x === '\u000D' || x === '\u2028' || x === '\u2029' } module.exports.isLineTerminatorJSON = function isLineTerminatorJSON(x) { return x === '\u000A' || x === '\u000D' } module.exports.isIdentifierStart = function isIdentifierStart(x) { return x === '$' || x === '_' || (x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '\u0080' && Uni.NonAsciiIdentifierStart.test(x)) } module.exports.isIdentifierPart = function isIdentifierPart(x) { return x === '$' || x === '_' || (x >= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x >= '0' && x <= '9') // <-- addition to Start || (x >= '\u0080' && Uni.NonAsciiIdentifierPart.test(x)) } module.exports.NonAsciiIdentifierStart = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0\u08A2-\u08AC\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0977\u0979-\u097F\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191C\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA697\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA80-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/ // ECMAScript 5.1/Unicode v6.3.0 NonAsciiIdentifierPart: module.exports.NonAsciiIdentifierPart = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u0527\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0\u08A2-\u08AC\u08E4-\u08FE\u0900-\u0963\u0966-\u096F\u0971-\u0977\u0979-\u097F\u0981-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C01-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C82\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D02\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F0\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191C\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1D00-\u1DE6\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA697\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA793\uA7A0-\uA7AA\uA7F8-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A\uAA7B\uAA80-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE26\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/ |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 30.77% | (4 / 13) | 0% | (0 / 4) | 0% | (0 / 4) | 30.77% | (4 / 13) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 1 1 1 1 | 'use strict';
var fs = require('fs');
var Promise = require('pinkie-promise');
module.exports = function (fp) {
var fn = typeof fs.access === 'function' ? fs.access : fs.stat;
return new Promise(function (resolve) {
fn(fp, function (err) {
resolve(!err);
});
});
};
module.exports.sync = function (fp) {
var fn = typeof fs.accessSync === 'function' ? fs.accessSync : fs.statSync;
try {
fn(fp);
return true;
} catch (err) {
return false;
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 45.45% | (5 / 11) | 12.5% | (1 / 8) | 0% | (0 / 2) | 45.45% | (5 / 11) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 1 1 1 1 1 | 'use strict'; function posix(path) { return path.charAt(0) === '/'; } function win32(path) { // https://github.com/nodejs/node/blob/b3fcc245fb25539909ef1d5eaa01dbf92e168633/lib/path.js#L56 var splitDeviceRe = /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/; var result = splitDeviceRe.exec(path); var device = result[1] || ''; var isUnc = Boolean(device && device.charAt(1) !== ':'); // UNC paths are always absolute return Boolean(result[2] || isUnc); } module.exports = process.platform === 'win32' ? win32 : posix; module.exports.posix = posix; module.exports.win32 = win32; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 41.18% | (14 / 34) | 3.85% | (1 / 26) | 0% | (0 / 4) | 41.18% | (14 / 34) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var isWindows = process.platform === 'win32';
// Regex to split a windows path into three parts: [*, device, slash,
// tail] windows-only
var splitDeviceRe =
/^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/;
// Regex to split the tail part of the above into [*, dir, basename, ext]
var splitTailRe =
/^([\s\S]*?)((?:\.{1,2}|[^\\\/]+?|)(\.[^.\/\\]*|))(?:[\\\/]*)$/;
var win32 = {};
// Function to split a filename into [root, dir, basename, ext]
function win32SplitPath(filename) {
// Separate device+slash from tail
var result = splitDeviceRe.exec(filename),
device = (result[1] || '') + (result[2] || ''),
tail = result[3] || '';
// Split the tail into dir, basename and extension
var result2 = splitTailRe.exec(tail),
dir = result2[1],
basename = result2[2],
ext = result2[3];
return [device, dir, basename, ext];
}
win32.parse = function(pathString) {
if (typeof pathString !== 'string') {
throw new TypeError(
"Parameter 'pathString' must be a string, not " + typeof pathString
);
}
var allParts = win32SplitPath(pathString);
if (!allParts || allParts.length !== 4) {
throw new TypeError("Invalid path '" + pathString + "'");
}
return {
root: allParts[0],
dir: allParts[0] + allParts[1].slice(0, -1),
base: allParts[2],
ext: allParts[3],
name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
};
};
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var posix = {};
function posixSplitPath(filename) {
return splitPathRe.exec(filename).slice(1);
}
posix.parse = function(pathString) {
if (typeof pathString !== 'string') {
throw new TypeError(
"Parameter 'pathString' must be a string, not " + typeof pathString
);
}
var allParts = posixSplitPath(pathString);
if (!allParts || allParts.length !== 4) {
throw new TypeError("Invalid path '" + pathString + "'");
}
allParts[1] = allParts[1] || '';
allParts[2] = allParts[2] || '';
allParts[3] = allParts[3] || '';
return {
root: allParts[0],
dir: allParts[0] + allParts[1].slice(0, -1),
base: allParts[2],
ext: allParts[3],
name: allParts[2].slice(0, allParts[2].length - allParts[3].length)
};
};
Iif (isWindows)
module.exports = win32.parse;
else /* posix */
module.exports = posix.parse;
module.exports.posix = posix.parse;
module.exports.win32 = win32.parse;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 61.11% | (11 / 18) | 0% | (0 / 4) | 0% | (0 / 3) | 61.11% | (11 / 18) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 1 1 1 1 1 1 1 1 1 1 1 | 'use strict';
var fs = require('graceful-fs');
var Promise = require('pinkie-promise');
var pify = require('pify');
function type(fn, fn2, fp) {
if (typeof fp !== 'string') {
return Promise.reject(new TypeError('Expected a string'));
}
return pify(fs[fn], Promise)(fp).then(function (stats) {
return stats[fn2]();
});
}
function typeSync(fn, fn2, fp) {
if (typeof fp !== 'string') {
throw new TypeError('Expected a string');
}
return fs[fn](fp)[fn2]();
}
exports.file = type.bind(null, 'stat', 'isFile');
exports.dir = type.bind(null, 'stat', 'isDirectory');
exports.symlink = type.bind(null, 'lstat', 'isSymbolicLink');
exports.fileSync = typeSync.bind(null, 'statSync', 'isFile');
exports.dirSync = typeSync.bind(null, 'statSync', 'isDirectory');
exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink');
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 8.33% | (3 / 36) | 0% | (0 / 22) | 0% | (0 / 9) | 8.33% | (3 / 36) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | 1 1 1 | 'use strict'; var processFn = function (fn, P, opts) { return function () { var that = this; var args = new Array(arguments.length); for (var i = 0; i < arguments.length; i++) { args[i] = arguments[i]; } return new P(function (resolve, reject) { args.push(function (err, result) { if (err) { reject(err); } else if (opts.multiArgs) { var results = new Array(arguments.length - 1); for (var i = 1; i < arguments.length; i++) { results[i - 1] = arguments[i]; } resolve(results); } else { resolve(result); } }); fn.apply(that, args); }); }; }; var pify = module.exports = function (obj, P, opts) { if (typeof P !== 'function') { opts = P; P = Promise; } opts = opts || {}; opts.exclude = opts.exclude || [/.+Sync$/]; var filter = function (key) { var match = function (pattern) { return typeof pattern === 'string' ? key === pattern : pattern.test(key); }; return opts.include ? opts.include.some(match) : !opts.exclude.some(match); }; var ret = typeof obj === 'function' ? function () { if (opts.excludeMain) { return obj.apply(this, arguments); } return processFn(obj, P, opts).apply(this, arguments); } : {}; return Object.keys(obj).reduce(function (ret, key) { var x = obj[key]; ret[key] = typeof x === 'function' && filter(key) ? processFn(x, P, opts) : x; return ret; }, ret); }; pify.all = pify; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 100% | (1 / 1) | 50% | (1 / 2) | 100% | (0 / 0) | 100% | (1 / 1) |
| 1 2 3 4 5 | 1 | 'use strict';
module.exports = typeof Promise === 'function' ? Promise : require('pinkie');
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 50% | (4 / 8) | 0% | (0 / 4) | 0% | (0 / 3) | 50% | (4 / 8) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 1 1 1 1 | 'use strict';
var path = require('path');
var findUp = require('find-up');
module.exports = function (cwd) {
return findUp('package.json', {cwd: cwd}).then(function (fp) {
return fp ? path.dirname(fp) : null;
});
};
module.exports.sync = function (cwd) {
var fp = findUp.sync('package.json', {cwd: cwd});
return fp ? path.dirname(fp) : null;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 36.36% | (4 / 11) | 100% | (0 / 0) | 0% | (0 / 5) | 36.36% | (4 / 11) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 1 1 1 1 | /*!
* preserve <https://github.com/jonschlinkert/preserve>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
/**
* Replace tokens in `str` with a temporary, heuristic placeholder.
*
* ```js
* tokens.before('{a\\,b}');
* //=> '{__ID1__}'
* ```
*
* @param {String} `str`
* @return {String} String with placeholders.
* @api public
*/
exports.before = function before(str, re) {
return str.replace(re, function (match) {
var id = randomize();
cache[id] = match;
return '__ID' + id + '__';
});
};
/**
* Replace placeholders in `str` with original tokens.
*
* ```js
* tokens.after('{__ID1__}');
* //=> '{a\\,b}'
* ```
*
* @param {String} `str` String with placeholders
* @return {String} `str` String with original tokens.
* @api public
*/
exports.after = function after(str) {
return str.replace(/__ID(.{5})__/g, function (_, id) {
return cache[id];
});
};
function randomize() {
return Math.random().toString().slice(2, 7);
}
var cache = {};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 14.63% | (6 / 41) | 0% | (0 / 28) | 0% | (0 / 1) | 18.75% | (6 / 32) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | 1 1 1 1 1 1 | /*!
* randomatic <https://github.com/jonschlinkert/randomatic>
*
* This was originally inspired by <http://stackoverflow.com/a/10727155/1267639>
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License (MIT)
*/
'use strict';
var isNumber = require('is-number');
var typeOf = require('kind-of');
/**
* Expose `randomatic`
*/
module.exports = randomatic;
/**
* Available mask characters
*/
var type = {
lower: 'abcdefghijklmnopqrstuvwxyz',
upper: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
number: '0123456789',
special: '~!@#$%^&()_+-={}[];\',.'
};
type.all = type.lower + type.upper + type.number;
/**
* Generate random character sequences of a specified `length`,
* based on the given `pattern`.
*
* @param {String} `pattern` The pattern to use for generating the random string.
* @param {String} `length` The length of the string to generate.
* @param {String} `options`
* @return {String}
* @api public
*/
function randomatic(pattern, length, options) {
if (typeof pattern === 'undefined') {
throw new Error('randomatic expects a string or number.');
}
var custom = false;
if (arguments.length === 1) {
if (typeof pattern === 'string') {
length = pattern.length;
} else if (isNumber(pattern)) {
options = {}; length = pattern; pattern = '*';
}
}
if (typeOf(length) === 'object' && length.hasOwnProperty('chars')) {
options = length;
pattern = options.chars;
length = pattern.length;
custom = true;
}
var opts = options || {};
var mask = '';
var res = '';
// Characters to be used
if (pattern.indexOf('?') !== -1) mask += opts.chars;
if (pattern.indexOf('a') !== -1) mask += type.lower;
if (pattern.indexOf('A') !== -1) mask += type.upper;
if (pattern.indexOf('0') !== -1) mask += type.number;
if (pattern.indexOf('!') !== -1) mask += type.special;
if (pattern.indexOf('*') !== -1) mask += type.all;
if (custom) mask += pattern;
while (length--) {
res += mask.charAt(parseInt(Math.random() * mask.length, 10));
}
return res;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 30.77% | (4 / 13) | 0% | (0 / 4) | 0% | (0 / 4) | 30.77% | (4 / 13) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 1 1 1 1 | 'use strict';
var findUp = require('find-up');
var readPkg = require('read-pkg');
module.exports = function (opts) {
return findUp('package.json', opts).then(function (fp) {
if (!fp) {
return {};
}
return readPkg(fp, opts).then(function (pkg) {
return {
pkg: pkg,
path: fp
};
});
});
};
module.exports.sync = function (opts) {
var fp = findUp.sync('package.json', opts);
if (!fp) {
return {};
}
return {
pkg: readPkg.sync(fp, opts),
path: fp
};
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 23.08% | (6 / 26) | 0% | (0 / 16) | 0% | (0 / 4) | 23.08% | (6 / 26) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 1 1 1 1 1 1 | 'use strict';
var path = require('path');
var loadJsonFile = require('load-json-file');
var normalizePackageData = require('normalize-package-data');
var pathType = require('path-type');
module.exports = function (fp, opts) {
if (typeof fp !== 'string') {
opts = fp;
fp = '.';
}
opts = opts || {};
return pathType.dir(fp)
.then(function (isDir) {
if (isDir) {
fp = path.join(fp, 'package.json');
}
return loadJsonFile(fp);
})
.then(function (x) {
if (opts.normalize !== false) {
normalizePackageData(x);
}
return x;
});
};
module.exports.sync = function (fp, opts) {
if (typeof fp !== 'string') {
opts = fp;
fp = '.';
}
opts = opts || {};
fp = pathType.dirSync(fp) ? path.join(fp, 'package.json') : fp;
var x = loadJsonFile.sync(fp);
if (opts.normalize !== false) {
normalizePackageData(x);
}
return x;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 34.62% | (9 / 26) | 0% | (0 / 18) | 0% | (0 / 2) | 34.62% | (9 / 26) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 1 1 1 1 1 1 1 1 1 | /*!
* regex-cache <https://github.com/jonschlinkert/regex-cache>
*
* Copyright (c) 2015 Jon Schlinkert.
* Licensed under the MIT license.
*/
'use strict';
var isPrimitive = require('is-primitive');
var equal = require('is-equal-shallow');
var basic = {};
var cache = {};
/**
* Expose `regexCache`
*/
module.exports = regexCache;
/**
* Memoize the results of a call to the new RegExp constructor.
*
* @param {Function} fn [description]
* @param {String} str [description]
* @param {Options} options [description]
* @param {Boolean} nocompare [description]
* @return {RegExp}
*/
function regexCache(fn, str, opts) {
var key = '_default_', regex, cached;
if (!str && !opts) {
if (typeof fn !== 'function') {
return fn;
}
return basic[key] || (basic[key] = fn(str));
}
var isString = typeof str === 'string';
if (isString) {
if (!opts) {
return basic[str] || (basic[str] = fn(str));
}
key = str;
} else {
opts = str;
}
cached = cache[key];
if (cached && equal(cached.opts, opts)) {
return cached.regex;
}
memo(key, opts, (regex = fn(str, opts)));
return regex;
}
function memo(key, opts, regex) {
cache[key] = {regex: regex, opts: opts};
}
/**
* Expose `cache`
*/
module.exports.cache = cache;
module.exports.basic = basic;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 20% | (1 / 5) | 100% | (0 / 0) | 0% | (0 / 1) | 20% | (1 / 5) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 1 | /*! * repeat-element <https://github.com/jonschlinkert/repeat-element> * * Copyright (c) 2015 Jon Schlinkert. * Licensed under the MIT license. */ 'use strict'; module.exports = function repeat(ele, num) { var arr = new Array(num); for (var i = 0; i < num; i++) { arr[i] = ele; } return arr; }; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 16.67% | (4 / 24) | 0% | (0 / 16) | 0% | (0 / 1) | 18.18% | (4 / 22) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | 1 1 1 1 | /*!
* repeat-string <https://github.com/jonschlinkert/repeat-string>
*
* Copyright (c) 2014-2015, Jon Schlinkert.
* Licensed under the MIT License.
*/
'use strict';
/**
* Results cache
*/
var res = '';
var cache;
/**
* Expose `repeat`
*/
module.exports = repeat;
/**
* Repeat the given `string` the specified `number`
* of times.
*
* **Example:**
*
* ```js
* var repeat = require('repeat-string');
* repeat('A', 5);
* //=> AAAAA
* ```
*
* @param {String} `string` The string to repeat
* @param {Number} `number` The number of times to repeat the string
* @return {String} Repeated string
* @api public
*/
function repeat(str, num) {
if (typeof str !== 'string') {
throw new TypeError('expected a string');
}
// cover common, quick use cases
if (num === 1) return str;
if (num === 2) return str + str;
var max = str.length * num;
if (cache !== str || typeof cache === 'undefined') {
cache = str;
res = '';
} else if (res.length >= max) {
return res.substr(0, max);
}
while (max > res.length && num > 1) {
if (num & 1) {
res += str;
}
num >>= 1;
str += str;
}
res += str;
res = res.substr(0, max);
return res;
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 25% | (3 / 12) | 0% | (0 / 10) | 0% | (0 / 3) | 27.27% | (3 / 11) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 1 1 1 | module.exports = function (_require) { _require = _require || require var main = _require.main if (main && isIISNode(main)) return handleIISNode(main) else return main ? main.filename : process.cwd() } function isIISNode (main) { return /\\iisnode\\/.test(main.filename) } function handleIISNode (main) { if (!main.children.length) { return main.filename } else { return main.children[0].filename } } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 30% | (3 / 10) | 0% | (0 / 4) | 0% | (0 / 1) | 30% | (3 / 10) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 1 1 1 | 'use strict';
var path = require('path');
var Module = require('module');
module.exports = function (fromDir, moduleId) {
if (typeof fromDir !== 'string' || typeof moduleId !== 'string') {
throw new TypeError('Expected `fromDir` and `moduleId` to be a string');
}
fromDir = path.resolve(fromDir);
var fromFile = path.join(fromDir, 'noop.js');
try {
return Module._resolveFilename(moduleId, {
id: fromFile,
filename: fromFile,
paths: Module._nodeModulePaths(fromDir)
});
} catch (err) {
return null;
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| rimraf.js | 9.91% | (21 / 212) | 0% | (0 / 152) | 0% | (0 / 27) | 9.95% | (21 / 211) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | module.exports = rimraf
rimraf.sync = rimrafSync
var assert = require("assert")
var path = require("path")
var fs = require("fs")
var glob = require("glob")
var defaultGlobOpts = {
nosort: true,
silent: true
}
// for EMFILE handling
var timeout = 0
var isWindows = (process.platform === "win32")
function defaults (options) {
var methods = [
'unlink',
'chmod',
'stat',
'lstat',
'rmdir',
'readdir'
]
methods.forEach(function(m) {
options[m] = options[m] || fs[m]
m = m + 'Sync'
options[m] = options[m] || fs[m]
})
options.maxBusyTries = options.maxBusyTries || 3
options.emfileWait = options.emfileWait || 1000
if (options.glob === false) {
options.disableGlob = true
}
options.disableGlob = options.disableGlob || false
options.glob = options.glob || defaultGlobOpts
}
function rimraf (p, options, cb) {
if (typeof options === 'function') {
cb = options
options = {}
}
assert(p, 'rimraf: missing path')
assert.equal(typeof p, 'string', 'rimraf: path should be a string')
assert.equal(typeof cb, 'function', 'rimraf: callback function required')
assert(options, 'rimraf: invalid options argument provided')
assert.equal(typeof options, 'object', 'rimraf: options should be object')
defaults(options)
var busyTries = 0
var errState = null
var n = 0
if (options.disableGlob || !glob.hasMagic(p))
return afterGlob(null, [p])
options.lstat(p, function (er, stat) {
if (!er)
return afterGlob(null, [p])
glob(p, options.glob, afterGlob)
})
function next (er) {
errState = errState || er
if (--n === 0)
cb(errState)
}
function afterGlob (er, results) {
if (er)
return cb(er)
n = results.length
if (n === 0)
return cb()
results.forEach(function (p) {
rimraf_(p, options, function CB (er) {
if (er) {
if ((er.code === "EBUSY" || er.code === "ENOTEMPTY" || er.code === "EPERM") &&
busyTries < options.maxBusyTries) {
busyTries ++
var time = busyTries * 100
// try again, with the same exact callback as this one.
return setTimeout(function () {
rimraf_(p, options, CB)
}, time)
}
// this one won't happen if graceful-fs is used.
if (er.code === "EMFILE" && timeout < options.emfileWait) {
return setTimeout(function () {
rimraf_(p, options, CB)
}, timeout ++)
}
// already gone
if (er.code === "ENOENT") er = null
}
timeout = 0
next(er)
})
})
}
}
// Two possible strategies.
// 1. Assume it's a file. unlink it, then do the dir stuff on EPERM or EISDIR
// 2. Assume it's a directory. readdir, then do the file stuff on ENOTDIR
//
// Both result in an extra syscall when you guess wrong. However, there
// are likely far more normal files in the world than directories. This
// is based on the assumption that a the average number of files per
// directory is >= 1.
//
// If anyone ever complains about this, then I guess the strategy could
// be made configurable somehow. But until then, YAGNI.
function rimraf_ (p, options, cb) {
assert(p)
assert(options)
assert(typeof cb === 'function')
// sunos lets the root user unlink directories, which is... weird.
// so we have to lstat here and make sure it's not a dir.
options.lstat(p, function (er, st) {
if (er && er.code === "ENOENT")
return cb(null)
// Windows can EPERM on stat. Life is suffering.
if (er && er.code === "EPERM" && isWindows)
fixWinEPERM(p, options, er, cb)
if (st && st.isDirectory())
return rmdir(p, options, er, cb)
options.unlink(p, function (er) {
if (er) {
if (er.code === "ENOENT")
return cb(null)
if (er.code === "EPERM")
return (isWindows)
? fixWinEPERM(p, options, er, cb)
: rmdir(p, options, er, cb)
if (er.code === "EISDIR")
return rmdir(p, options, er, cb)
}
return cb(er)
})
})
}
function fixWinEPERM (p, options, er, cb) {
assert(p)
assert(options)
assert(typeof cb === 'function')
if (er)
assert(er instanceof Error)
options.chmod(p, 666, function (er2) {
if (er2)
cb(er2.code === "ENOENT" ? null : er)
else
options.stat(p, function(er3, stats) {
if (er3)
cb(er3.code === "ENOENT" ? null : er)
else if (stats.isDirectory())
rmdir(p, options, er, cb)
else
options.unlink(p, cb)
})
})
}
function fixWinEPERMSync (p, options, er) {
assert(p)
assert(options)
if (er)
assert(er instanceof Error)
try {
options.chmodSync(p, 666)
} catch (er2) {
if (er2.code === "ENOENT")
return
else
throw er
}
try {
var stats = options.statSync(p)
} catch (er3) {
if (er3.code === "ENOENT")
return
else
throw er
}
if (stats.isDirectory())
rmdirSync(p, options, er)
else
options.unlinkSync(p)
}
function rmdir (p, options, originalEr, cb) {
assert(p)
assert(options)
if (originalEr)
assert(originalEr instanceof Error)
assert(typeof cb === 'function')
// try to rmdir first, and only readdir on ENOTEMPTY or EEXIST (SunOS)
// if we guessed wrong, and it's not a directory, then
// raise the original error.
options.rmdir(p, function (er) {
if (er && (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM"))
rmkids(p, options, cb)
else if (er && er.code === "ENOTDIR")
cb(originalEr)
else
cb(er)
})
}
function rmkids(p, options, cb) {
assert(p)
assert(options)
assert(typeof cb === 'function')
options.readdir(p, function (er, files) {
if (er)
return cb(er)
var n = files.length
if (n === 0)
return options.rmdir(p, cb)
var errState
files.forEach(function (f) {
rimraf(path.join(p, f), options, function (er) {
if (errState)
return
if (er)
return cb(errState = er)
if (--n === 0)
options.rmdir(p, cb)
})
})
})
}
// this looks simpler, and is strictly *faster*, but will
// tie up the JavaScript thread and fail on excessively
// deep directory trees.
function rimrafSync (p, options) {
options = options || {}
defaults(options)
assert(p, 'rimraf: missing path')
assert.equal(typeof p, 'string', 'rimraf: path should be a string')
assert(options, 'rimraf: missing options')
assert.equal(typeof options, 'object', 'rimraf: options should be object')
var results
if (options.disableGlob || !glob.hasMagic(p)) {
results = [p]
} else {
try {
options.lstatSync(p)
results = [p]
} catch (er) {
results = glob.sync(p, options.glob)
}
}
if (!results.length)
return
for (var i = 0; i < results.length; i++) {
var p = results[i]
try {
var st = options.lstatSync(p)
} catch (er) {
if (er.code === "ENOENT")
return
// Windows can EPERM on stat. Life is suffering.
if (er.code === "EPERM" && isWindows)
fixWinEPERMSync(p, options, er)
}
try {
// sunos lets the root user unlink directories, which is... weird.
if (st && st.isDirectory())
rmdirSync(p, options, null)
else
options.unlinkSync(p)
} catch (er) {
if (er.code === "ENOENT")
return
if (er.code === "EPERM")
return isWindows ? fixWinEPERMSync(p, options, er) : rmdirSync(p, options, er)
if (er.code !== "EISDIR")
throw er
rmdirSync(p, options, er)
}
}
}
function rmdirSync (p, options, originalEr) {
assert(p)
assert(options)
if (originalEr)
assert(originalEr instanceof Error)
try {
options.rmdirSync(p)
} catch (er) {
if (er.code === "ENOENT")
return
if (er.code === "ENOTDIR")
throw originalEr
if (er.code === "ENOTEMPTY" || er.code === "EEXIST" || er.code === "EPERM")
rmkidsSync(p, options)
}
}
function rmkidsSync (p, options) {
assert(p)
assert(options)
options.readdirSync(p).forEach(function (f) {
rimrafSync(path.join(p, f), options)
})
// We only end up here once we got ENOTEMPTY at least once, and
// at this point, we are guaranteed to have removed all the kids.
// So, we know that it won't be ENOENT or ENOTDIR or anything else.
// try really hard to delete stuff on windows, because it has a
// PROFOUNDLY annoying habit of not closing handles promptly when
// files are deleted, resulting in spurious ENOTEMPTY errors.
var retries = isWindows ? 100 : 1
var i = 0
do {
var threw = true
try {
var ret = options.rmdirSync(p, options)
threw = false
return ret
} finally {
if (++i < retries && threw)
continue
}
} while (true)
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| semver.js | 27.46% | (184 / 670) | 1.91% | (7 / 366) | 1.22% | (1 / 82) | 27.88% | (184 / 660) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 34 34 31 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | exports = module.exports = SemVer; // The debug function is excluded entirely from the minified version. /* nomin */ var debug; /* nomin */ Iif (typeof process === 'object' && /* nomin */ process.env && /* nomin */ process.env.NODE_DEBUG && /* nomin */ /\bsemver\b/i.test(process.env.NODE_DEBUG)) /* nomin */ debug = function() { /* nomin */ var args = Array.prototype.slice.call(arguments, 0); /* nomin */ args.unshift('SEMVER'); /* nomin */ console.log.apply(console, args); /* nomin */ }; /* nomin */ else /* nomin */ debug = function() {}; // Note: this is the semver.org version of the spec that it implements // Not necessarily the package version of this code. exports.SEMVER_SPEC_VERSION = '2.0.0'; var MAX_LENGTH = 256; var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991; // The actual regexps go on exports.re var re = exports.re = []; var src = exports.src = []; var R = 0; // The following Regular Expressions can be used for tokenizing, // validating, and parsing SemVer version strings. // ## Numeric Identifier // A single `0`, or a non-zero digit followed by zero or more digits. var NUMERICIDENTIFIER = R++; src[NUMERICIDENTIFIER] = '0|[1-9]\\d*'; var NUMERICIDENTIFIERLOOSE = R++; src[NUMERICIDENTIFIERLOOSE] = '[0-9]+'; // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. var NONNUMERICIDENTIFIER = R++; src[NONNUMERICIDENTIFIER] = '\\d*[a-zA-Z-][a-zA-Z0-9-]*'; // ## Main Version // Three dot-separated numeric identifiers. var MAINVERSION = R++; src[MAINVERSION] = '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')\\.' + '(' + src[NUMERICIDENTIFIER] + ')'; var MAINVERSIONLOOSE = R++; src[MAINVERSIONLOOSE] = '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')\\.' + '(' + src[NUMERICIDENTIFIERLOOSE] + ')'; // ## Pre-release Version Identifier // A numeric identifier, or a non-numeric identifier. var PRERELEASEIDENTIFIER = R++; src[PRERELEASEIDENTIFIER] = '(?:' + src[NUMERICIDENTIFIER] + '|' + src[NONNUMERICIDENTIFIER] + ')'; var PRERELEASEIDENTIFIERLOOSE = R++; src[PRERELEASEIDENTIFIERLOOSE] = '(?:' + src[NUMERICIDENTIFIERLOOSE] + '|' + src[NONNUMERICIDENTIFIER] + ')'; // ## Pre-release Version // Hyphen, followed by one or more dot-separated pre-release version // identifiers. var PRERELEASE = R++; src[PRERELEASE] = '(?:-(' + src[PRERELEASEIDENTIFIER] + '(?:\\.' + src[PRERELEASEIDENTIFIER] + ')*))'; var PRERELEASELOOSE = R++; src[PRERELEASELOOSE] = '(?:-?(' + src[PRERELEASEIDENTIFIERLOOSE] + '(?:\\.' + src[PRERELEASEIDENTIFIERLOOSE] + ')*))'; // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. var BUILDIDENTIFIER = R++; src[BUILDIDENTIFIER] = '[0-9A-Za-z-]+'; // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata // identifiers. var BUILD = R++; src[BUILD] = '(?:\\+(' + src[BUILDIDENTIFIER] + '(?:\\.' + src[BUILDIDENTIFIER] + ')*))'; // ## Full Version String // A main version, followed optionally by a pre-release version and // build metadata. // Note that the only major, minor, patch, and pre-release sections of // the version string are capturing groups. The build metadata is not a // capturing group, because it should not ever be used in version // comparison. var FULL = R++; var FULLPLAIN = 'v?' + src[MAINVERSION] + src[PRERELEASE] + '?' + src[BUILD] + '?'; src[FULL] = '^' + FULLPLAIN + '$'; // like full, but allows v1.2.3 and =1.2.3, which people do sometimes. // also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty // common in the npm registry. var LOOSEPLAIN = '[v=\\s]*' + src[MAINVERSIONLOOSE] + src[PRERELEASELOOSE] + '?' + src[BUILD] + '?'; var LOOSE = R++; src[LOOSE] = '^' + LOOSEPLAIN + '$'; var GTLT = R++; src[GTLT] = '((?:<|>)?=?)'; // Something like "2.*" or "1.2.x". // Note that "x.x" is a valid xRange identifer, meaning "any version" // Only the first item is strictly required. var XRANGEIDENTIFIERLOOSE = R++; src[XRANGEIDENTIFIERLOOSE] = src[NUMERICIDENTIFIERLOOSE] + '|x|X|\\*'; var XRANGEIDENTIFIER = R++; src[XRANGEIDENTIFIER] = src[NUMERICIDENTIFIER] + '|x|X|\\*'; var XRANGEPLAIN = R++; src[XRANGEPLAIN] = '[v=\\s]*(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIER] + ')' + '(?:' + src[PRERELEASE] + ')?' + src[BUILD] + '?' + ')?)?'; var XRANGEPLAINLOOSE = R++; src[XRANGEPLAINLOOSE] = '[v=\\s]*(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:\\.(' + src[XRANGEIDENTIFIERLOOSE] + ')' + '(?:' + src[PRERELEASELOOSE] + ')?' + src[BUILD] + '?' + ')?)?'; var XRANGE = R++; src[XRANGE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAIN] + '$'; var XRANGELOOSE = R++; src[XRANGELOOSE] = '^' + src[GTLT] + '\\s*' + src[XRANGEPLAINLOOSE] + '$'; // Tilde ranges. // Meaning is "reasonably at or greater than" var LONETILDE = R++; src[LONETILDE] = '(?:~>?)'; var TILDETRIM = R++; src[TILDETRIM] = '(\\s*)' + src[LONETILDE] + '\\s+'; re[TILDETRIM] = new RegExp(src[TILDETRIM], 'g'); var tildeTrimReplace = '$1~'; var TILDE = R++; src[TILDE] = '^' + src[LONETILDE] + src[XRANGEPLAIN] + '$'; var TILDELOOSE = R++; src[TILDELOOSE] = '^' + src[LONETILDE] + src[XRANGEPLAINLOOSE] + '$'; // Caret ranges. // Meaning is "at least and backwards compatible with" var LONECARET = R++; src[LONECARET] = '(?:\\^)'; var CARETTRIM = R++; src[CARETTRIM] = '(\\s*)' + src[LONECARET] + '\\s+'; re[CARETTRIM] = new RegExp(src[CARETTRIM], 'g'); var caretTrimReplace = '$1^'; var CARET = R++; src[CARET] = '^' + src[LONECARET] + src[XRANGEPLAIN] + '$'; var CARETLOOSE = R++; src[CARETLOOSE] = '^' + src[LONECARET] + src[XRANGEPLAINLOOSE] + '$'; // A simple gt/lt/eq thing, or just "" to indicate "any version" var COMPARATORLOOSE = R++; src[COMPARATORLOOSE] = '^' + src[GTLT] + '\\s*(' + LOOSEPLAIN + ')$|^$'; var COMPARATOR = R++; src[COMPARATOR] = '^' + src[GTLT] + '\\s*(' + FULLPLAIN + ')$|^$'; // An expression to strip any whitespace between the gtlt and the thing // it modifies, so that `> 1.2.3` ==> `>1.2.3` var COMPARATORTRIM = R++; src[COMPARATORTRIM] = '(\\s*)' + src[GTLT] + '\\s*(' + LOOSEPLAIN + '|' + src[XRANGEPLAIN] + ')'; // this one has to use the /g flag re[COMPARATORTRIM] = new RegExp(src[COMPARATORTRIM], 'g'); var comparatorTrimReplace = '$1$2$3'; // Something like `1.2.3 - 1.2.4` // Note that these all use the loose form, because they'll be // checked against either the strict or loose comparator form // later. var HYPHENRANGE = R++; src[HYPHENRANGE] = '^\\s*(' + src[XRANGEPLAIN] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAIN] + ')' + '\\s*$'; var HYPHENRANGELOOSE = R++; src[HYPHENRANGELOOSE] = '^\\s*(' + src[XRANGEPLAINLOOSE] + ')' + '\\s+-\\s+' + '(' + src[XRANGEPLAINLOOSE] + ')' + '\\s*$'; // Star ranges basically just allow anything at all. var STAR = R++; src[STAR] = '(<|>)?=?\\s*\\*'; // Compile to actual regexp objects. // All are flag-free, unless they were created above with a flag. for (var i = 0; i < R; i++) { debug(i, src[i]); if (!re[i]) re[i] = new RegExp(src[i]); } exports.parse = parse; function parse(version, loose) { if (version instanceof SemVer) return version; if (typeof version !== 'string') return null; if (version.length > MAX_LENGTH) return null; var r = loose ? re[LOOSE] : re[FULL]; if (!r.test(version)) return null; try { return new SemVer(version, loose); } catch (er) { return null; } } exports.valid = valid; function valid(version, loose) { var v = parse(version, loose); return v ? v.version : null; } exports.clean = clean; function clean(version, loose) { var s = parse(version.trim().replace(/^[=v]+/, ''), loose); return s ? s.version : null; } exports.SemVer = SemVer; function SemVer(version, loose) { if (version instanceof SemVer) { if (version.loose === loose) return version; else version = version.version; } else if (typeof version !== 'string') { throw new TypeError('Invalid Version: ' + version); } if (version.length > MAX_LENGTH) throw new TypeError('version is longer than ' + MAX_LENGTH + ' characters') if (!(this instanceof SemVer)) return new SemVer(version, loose); debug('SemVer', version, loose); this.loose = loose; var m = version.trim().match(loose ? re[LOOSE] : re[FULL]); if (!m) throw new TypeError('Invalid Version: ' + version); this.raw = version; // these are actually numbers this.major = +m[1]; this.minor = +m[2]; this.patch = +m[3]; if (this.major > MAX_SAFE_INTEGER || this.major < 0) throw new TypeError('Invalid major version') if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) throw new TypeError('Invalid minor version') if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) throw new TypeError('Invalid patch version') // numberify any prerelease numeric ids if (!m[4]) this.prerelease = []; else this.prerelease = m[4].split('.').map(function(id) { if (/^[0-9]+$/.test(id)) { var num = +id; if (num >= 0 && num < MAX_SAFE_INTEGER) return num; } return id; }); this.build = m[5] ? m[5].split('.') : []; this.format(); } SemVer.prototype.format = function() { this.version = this.major + '.' + this.minor + '.' + this.patch; if (this.prerelease.length) this.version += '-' + this.prerelease.join('.'); return this.version; }; SemVer.prototype.toString = function() { return this.version; }; SemVer.prototype.compare = function(other) { debug('SemVer.compare', this.version, this.loose, other); if (!(other instanceof SemVer)) other = new SemVer(other, this.loose); return this.compareMain(other) || this.comparePre(other); }; SemVer.prototype.compareMain = function(other) { if (!(other instanceof SemVer)) other = new SemVer(other, this.loose); return compareIdentifiers(this.major, other.major) || compareIdentifiers(this.minor, other.minor) || compareIdentifiers(this.patch, other.patch); }; SemVer.prototype.comparePre = function(other) { if (!(other instanceof SemVer)) other = new SemVer(other, this.loose); // NOT having a prerelease is > having one if (this.prerelease.length && !other.prerelease.length) return -1; else if (!this.prerelease.length && other.prerelease.length) return 1; else if (!this.prerelease.length && !other.prerelease.length) return 0; var i = 0; do { var a = this.prerelease[i]; var b = other.prerelease[i]; debug('prerelease compare', i, a, b); if (a === undefined && b === undefined) return 0; else if (b === undefined) return 1; else if (a === undefined) return -1; else if (a === b) continue; else return compareIdentifiers(a, b); } while (++i); }; // preminor will bump the version up to the next minor release, and immediately // down to pre-release. premajor and prepatch work the same way. SemVer.prototype.inc = function(release, identifier) { switch (release) { case 'premajor': this.prerelease.length = 0; this.patch = 0; this.minor = 0; this.major++; this.inc('pre', identifier); break; case 'preminor': this.prerelease.length = 0; this.patch = 0; this.minor++; this.inc('pre', identifier); break; case 'prepatch': // If this is already a prerelease, it will bump to the next version // drop any prereleases that might already exist, since they are not // relevant at this point. this.prerelease.length = 0; this.inc('patch', identifier); this.inc('pre', identifier); break; // If the input is a non-prerelease version, this acts the same as // prepatch. case 'prerelease': if (this.prerelease.length === 0) this.inc('patch', identifier); this.inc('pre', identifier); break; case 'major': // If this is a pre-major version, bump up to the same major version. // Otherwise increment major. // 1.0.0-5 bumps to 1.0.0 // 1.1.0 bumps to 2.0.0 if (this.minor !== 0 || this.patch !== 0 || this.prerelease.length === 0) this.major++; this.minor = 0; this.patch = 0; this.prerelease = []; break; case 'minor': // If this is a pre-minor version, bump up to the same minor version. // Otherwise increment minor. // 1.2.0-5 bumps to 1.2.0 // 1.2.1 bumps to 1.3.0 if (this.patch !== 0 || this.prerelease.length === 0) this.minor++; this.patch = 0; this.prerelease = []; break; case 'patch': // If this is not a pre-release version, it will increment the patch. // If it is a pre-release it will bump up to the same patch version. // 1.2.0-5 patches to 1.2.0 // 1.2.0 patches to 1.2.1 if (this.prerelease.length === 0) this.patch++; this.prerelease = []; break; // This probably shouldn't be used publicly. // 1.0.0 "pre" would become 1.0.0-0 which is the wrong direction. case 'pre': if (this.prerelease.length === 0) this.prerelease = [0]; else { var i = this.prerelease.length; while (--i >= 0) { if (typeof this.prerelease[i] === 'number') { this.prerelease[i]++; i = -2; } } if (i === -1) // didn't increment anything this.prerelease.push(0); } if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 if (this.prerelease[0] === identifier) { if (isNaN(this.prerelease[1])) this.prerelease = [identifier, 0]; } else this.prerelease = [identifier, 0]; } break; default: throw new Error('invalid increment argument: ' + release); } this.format(); this.raw = this.version; return this; }; exports.inc = inc; function inc(version, release, loose, identifier) { if (typeof(loose) === 'string') { identifier = loose; loose = undefined; } try { return new SemVer(version, loose).inc(release, identifier).version; } catch (er) { return null; } } exports.diff = diff; function diff(version1, version2) { if (eq(version1, version2)) { return null; } else { var v1 = parse(version1); var v2 = parse(version2); if (v1.prerelease.length || v2.prerelease.length) { for (var key in v1) { if (key === 'major' || key === 'minor' || key === 'patch') { if (v1[key] !== v2[key]) { return 'pre'+key; } } } return 'prerelease'; } for (var key in v1) { if (key === 'major' || key === 'minor' || key === 'patch') { if (v1[key] !== v2[key]) { return key; } } } } } exports.compareIdentifiers = compareIdentifiers; var numeric = /^[0-9]+$/; function compareIdentifiers(a, b) { var anum = numeric.test(a); var bnum = numeric.test(b); if (anum && bnum) { a = +a; b = +b; } return (anum && !bnum) ? -1 : (bnum && !anum) ? 1 : a < b ? -1 : a > b ? 1 : 0; } exports.rcompareIdentifiers = rcompareIdentifiers; function rcompareIdentifiers(a, b) { return compareIdentifiers(b, a); } exports.major = major; function major(a, loose) { return new SemVer(a, loose).major; } exports.minor = minor; function minor(a, loose) { return new SemVer(a, loose).minor; } exports.patch = patch; function patch(a, loose) { return new SemVer(a, loose).patch; } exports.compare = compare; function compare(a, b, loose) { return new SemVer(a, loose).compare(b); } exports.compareLoose = compareLoose; function compareLoose(a, b) { return compare(a, b, true); } exports.rcompare = rcompare; function rcompare(a, b, loose) { return compare(b, a, loose); } exports.sort = sort; function sort(list, loose) { return list.sort(function(a, b) { return exports.compare(a, b, loose); }); } exports.rsort = rsort; function rsort(list, loose) { return list.sort(function(a, b) { return exports.rcompare(a, b, loose); }); } exports.gt = gt; function gt(a, b, loose) { return compare(a, b, loose) > 0; } exports.lt = lt; function lt(a, b, loose) { return compare(a, b, loose) < 0; } exports.eq = eq; function eq(a, b, loose) { return compare(a, b, loose) === 0; } exports.neq = neq; function neq(a, b, loose) { return compare(a, b, loose) !== 0; } exports.gte = gte; function gte(a, b, loose) { return compare(a, b, loose) >= 0; } exports.lte = lte; function lte(a, b, loose) { return compare(a, b, loose) <= 0; } exports.cmp = cmp; function cmp(a, op, b, loose) { var ret; switch (op) { case '===': if (typeof a === 'object') a = a.version; if (typeof b === 'object') b = b.version; ret = a === b; break; case '!==': if (typeof a === 'object') a = a.version; if (typeof b === 'object') b = b.version; ret = a !== b; break; case '': case '=': case '==': ret = eq(a, b, loose); break; case '!=': ret = neq(a, b, loose); break; case '>': ret = gt(a, b, loose); break; case '>=': ret = gte(a, b, loose); break; case '<': ret = lt(a, b, loose); break; case '<=': ret = lte(a, b, loose); break; default: throw new TypeError('Invalid operator: ' + op); } return ret; } exports.Comparator = Comparator; function Comparator(comp, loose) { if (comp instanceof Comparator) { if (comp.loose === loose) return comp; else comp = comp.value; } if (!(this instanceof Comparator)) return new Comparator(comp, loose); debug('comparator', comp, loose); this.loose = loose; this.parse(comp); if (this.semver === ANY) this.value = ''; else this.value = this.operator + this.semver.version; debug('comp', this); } var ANY = {}; Comparator.prototype.parse = function(comp) { var r = this.loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; var m = comp.match(r); if (!m) throw new TypeError('Invalid comparator: ' + comp); this.operator = m[1]; if (this.operator === '=') this.operator = ''; // if it literally is just '>' or '' then allow anything. if (!m[2]) this.semver = ANY; else this.semver = new SemVer(m[2], this.loose); }; Comparator.prototype.toString = function() { return this.value; }; Comparator.prototype.test = function(version) { debug('Comparator.test', version, this.loose); if (this.semver === ANY) return true; if (typeof version === 'string') version = new SemVer(version, this.loose); return cmp(version, this.operator, this.semver, this.loose); }; exports.Range = Range; function Range(range, loose) { if ((range instanceof Range) && range.loose === loose) return range; if (!(this instanceof Range)) return new Range(range, loose); this.loose = loose; // First, split based on boolean or || this.raw = range; this.set = range.split(/\s*\|\|\s*/).map(function(range) { return this.parseRange(range.trim()); }, this).filter(function(c) { // throw out any that are not relevant for whatever reason return c.length; }); if (!this.set.length) { throw new TypeError('Invalid SemVer Range: ' + range); } this.format(); } Range.prototype.format = function() { this.range = this.set.map(function(comps) { return comps.join(' ').trim(); }).join('||').trim(); return this.range; }; Range.prototype.toString = function() { return this.range; }; Range.prototype.parseRange = function(range) { var loose = this.loose; range = range.trim(); debug('range', range, loose); // `1.2.3 - 1.2.4` => `>=1.2.3 <=1.2.4` var hr = loose ? re[HYPHENRANGELOOSE] : re[HYPHENRANGE]; range = range.replace(hr, hyphenReplace); debug('hyphen replace', range); // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` range = range.replace(re[COMPARATORTRIM], comparatorTrimReplace); debug('comparator trim', range, re[COMPARATORTRIM]); // `~ 1.2.3` => `~1.2.3` range = range.replace(re[TILDETRIM], tildeTrimReplace); // `^ 1.2.3` => `^1.2.3` range = range.replace(re[CARETTRIM], caretTrimReplace); // normalize spaces range = range.split(/\s+/).join(' '); // At this point, the range is completely trimmed and // ready to be split into comparators. var compRe = loose ? re[COMPARATORLOOSE] : re[COMPARATOR]; var set = range.split(' ').map(function(comp) { return parseComparator(comp, loose); }).join(' ').split(/\s+/); if (this.loose) { // in loose mode, throw out any that are not valid comparators set = set.filter(function(comp) { return !!comp.match(compRe); }); } set = set.map(function(comp) { return new Comparator(comp, loose); }); return set; }; // Mostly just for testing and legacy API reasons exports.toComparators = toComparators; function toComparators(range, loose) { return new Range(range, loose).set.map(function(comp) { return comp.map(function(c) { return c.value; }).join(' ').trim().split(' '); }); } // comprised of xranges, tildes, stars, and gtlt's at this point. // already replaced the hyphen ranges // turn into a set of JUST comparators. function parseComparator(comp, loose) { debug('comp', comp); comp = replaceCarets(comp, loose); debug('caret', comp); comp = replaceTildes(comp, loose); debug('tildes', comp); comp = replaceXRanges(comp, loose); debug('xrange', comp); comp = replaceStars(comp, loose); debug('stars', comp); return comp; } function isX(id) { return !id || id.toLowerCase() === 'x' || id === '*'; } // ~, ~> --> * (any, kinda silly) // ~2, ~2.x, ~2.x.x, ~>2, ~>2.x ~>2.x.x --> >=2.0.0 <3.0.0 // ~2.0, ~2.0.x, ~>2.0, ~>2.0.x --> >=2.0.0 <2.1.0 // ~1.2, ~1.2.x, ~>1.2, ~>1.2.x --> >=1.2.0 <1.3.0 // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0 function replaceTildes(comp, loose) { return comp.trim().split(/\s+/).map(function(comp) { return replaceTilde(comp, loose); }).join(' '); } function replaceTilde(comp, loose) { var r = loose ? re[TILDELOOSE] : re[TILDE]; return comp.replace(r, function(_, M, m, p, pr) { debug('tilde', comp, _, M, m, p, pr); var ret; if (isX(M)) ret = ''; else if (isX(m)) ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; else if (isX(p)) // ~1.2 == >=1.2.0 <1.3.0 ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; else if (pr) { debug('replaceTilde pr', pr); if (pr.charAt(0) !== '-') pr = '-' + pr; ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + (+m + 1) + '.0'; } else // ~1.2.3 == >=1.2.3 <1.3.0 ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0'; debug('tilde return', ret); return ret; }); } // ^ --> * (any, kinda silly) // ^2, ^2.x, ^2.x.x --> >=2.0.0 <3.0.0 // ^2.0, ^2.0.x --> >=2.0.0 <3.0.0 // ^1.2, ^1.2.x --> >=1.2.0 <2.0.0 // ^1.2.3 --> >=1.2.3 <2.0.0 // ^1.2.0 --> >=1.2.0 <2.0.0 function replaceCarets(comp, loose) { return comp.trim().split(/\s+/).map(function(comp) { return replaceCaret(comp, loose); }).join(' '); } function replaceCaret(comp, loose) { debug('caret', comp, loose); var r = loose ? re[CARETLOOSE] : re[CARET]; return comp.replace(r, function(_, M, m, p, pr) { debug('caret', comp, _, M, m, p, pr); var ret; if (isX(M)) ret = ''; else if (isX(m)) ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; else if (isX(p)) { if (M === '0') ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; else ret = '>=' + M + '.' + m + '.0 <' + (+M + 1) + '.0.0'; } else if (pr) { debug('replaceCaret pr', pr); if (pr.charAt(0) !== '-') pr = '-' + pr; if (M === '0') { if (m === '0') ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + m + '.' + (+p + 1); else ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + M + '.' + (+m + 1) + '.0'; } else ret = '>=' + M + '.' + m + '.' + p + pr + ' <' + (+M + 1) + '.0.0'; } else { debug('no pr'); if (M === '0') { if (m === '0') ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + m + '.' + (+p + 1); else ret = '>=' + M + '.' + m + '.' + p + ' <' + M + '.' + (+m + 1) + '.0'; } else ret = '>=' + M + '.' + m + '.' + p + ' <' + (+M + 1) + '.0.0'; } debug('caret return', ret); return ret; }); } function replaceXRanges(comp, loose) { debug('replaceXRanges', comp, loose); return comp.split(/\s+/).map(function(comp) { return replaceXRange(comp, loose); }).join(' '); } function replaceXRange(comp, loose) { comp = comp.trim(); var r = loose ? re[XRANGELOOSE] : re[XRANGE]; return comp.replace(r, function(ret, gtlt, M, m, p, pr) { debug('xRange', comp, ret, gtlt, M, m, p, pr); var xM = isX(M); var xm = xM || isX(m); var xp = xm || isX(p); var anyX = xp; if (gtlt === '=' && anyX) gtlt = ''; if (xM) { if (gtlt === '>' || gtlt === '<') { // nothing is allowed ret = '<0.0.0'; } else { // nothing is forbidden ret = '*'; } } else if (gtlt && anyX) { // replace X with 0 if (xm) m = 0; if (xp) p = 0; if (gtlt === '>') { // >1 => >=2.0.0 // >1.2 => >=1.3.0 // >1.2.3 => >= 1.2.4 gtlt = '>='; if (xm) { M = +M + 1; m = 0; p = 0; } else if (xp) { m = +m + 1; p = 0; } } else if (gtlt === '<=') { // <=0.7.x is actually <0.8.0, since any 0.7.x should // pass. Similarly, <=7.x is actually <8.0.0, etc. gtlt = '<'; if (xm) M = +M + 1; else m = +m + 1; } ret = gtlt + M + '.' + m + '.' + p; } else if (xm) { ret = '>=' + M + '.0.0 <' + (+M + 1) + '.0.0'; } else if (xp) { ret = '>=' + M + '.' + m + '.0 <' + M + '.' + (+m + 1) + '.0'; } debug('xRange return', ret); return ret; }); } // Because * is AND-ed with everything else in the comparator, // and '' means "any version", just remove the *s entirely. function replaceStars(comp, loose) { debug('replaceStars', comp, loose); // Looseness is ignored here. star is always as loose as it gets! return comp.trim().replace(re[STAR], ''); } // This function is passed to string.replace(re[HYPHENRANGE]) // M, m, patch, prerelease, build // 1.2 - 3.4.5 => >=1.2.0 <=3.4.5 // 1.2.3 - 3.4 => >=1.2.0 <3.5.0 Any 3.4.x will do // 1.2 - 3.4 => >=1.2.0 <3.5.0 function hyphenReplace($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr, tb) { if (isX(fM)) from = ''; else if (isX(fm)) from = '>=' + fM + '.0.0'; else if (isX(fp)) from = '>=' + fM + '.' + fm + '.0'; else from = '>=' + from; if (isX(tM)) to = ''; else if (isX(tm)) to = '<' + (+tM + 1) + '.0.0'; else if (isX(tp)) to = '<' + tM + '.' + (+tm + 1) + '.0'; else if (tpr) to = '<=' + tM + '.' + tm + '.' + tp + '-' + tpr; else to = '<=' + to; return (from + ' ' + to).trim(); } // if ANY of the sets match ALL of its comparators, then pass Range.prototype.test = function(version) { if (!version) return false; if (typeof version === 'string') version = new SemVer(version, this.loose); for (var i = 0; i < this.set.length; i++) { if (testSet(this.set[i], version)) return true; } return false; }; function testSet(set, version) { for (var i = 0; i < set.length; i++) { if (!set[i].test(version)) return false; } if (version.prerelease.length) { // Find the set of versions that are allowed to have prereleases // For example, ^1.2.3-pr.1 desugars to >=1.2.3-pr.1 <2.0.0 // That should allow `1.2.3-pr.2` to pass. // However, `1.2.4-alpha.notready` should NOT be allowed, // even though it's within the range set by the comparators. for (var i = 0; i < set.length; i++) { debug(set[i].semver); if (set[i].semver === ANY) continue; if (set[i].semver.prerelease.length > 0) { var allowed = set[i].semver; if (allowed.major === version.major && allowed.minor === version.minor && allowed.patch === version.patch) return true; } } // Version has a -pre, but it's not one of the ones we like. return false; } return true; } exports.satisfies = satisfies; function satisfies(version, range, loose) { try { range = new Range(range, loose); } catch (er) { return false; } return range.test(version); } exports.maxSatisfying = maxSatisfying; function maxSatisfying(versions, range, loose) { return versions.filter(function(version) { return satisfies(version, range, loose); }).sort(function(a, b) { return rcompare(a, b, loose); })[0] || null; } exports.minSatisfying = minSatisfying; function minSatisfying(versions, range, loose) { return versions.filter(function(version) { return satisfies(version, range, loose); }).sort(function(a, b) { return compare(a, b, loose); })[0] || null; } exports.validRange = validRange; function validRange(range, loose) { try { // Return '*' instead of '' so that truthiness works. // This will throw if it's invalid anyway return new Range(range, loose).range || '*'; } catch (er) { return null; } } // Determine if version is less than all the versions possible in the range exports.ltr = ltr; function ltr(version, range, loose) { return outside(version, range, '<', loose); } // Determine if version is greater than all the versions possible in the range. exports.gtr = gtr; function gtr(version, range, loose) { return outside(version, range, '>', loose); } exports.outside = outside; function outside(version, range, hilo, loose) { version = new SemVer(version, loose); range = new Range(range, loose); var gtfn, ltefn, ltfn, comp, ecomp; switch (hilo) { case '>': gtfn = gt; ltefn = lte; ltfn = lt; comp = '>'; ecomp = '>='; break; case '<': gtfn = lt; ltefn = gte; ltfn = gt; comp = '<'; ecomp = '<='; break; default: throw new TypeError('Must provide a hilo val of "<" or ">"'); } // If it satisifes the range it is not outside if (satisfies(version, range, loose)) { return false; } // From now on, variable terms are as if we're in "gtr" mode. // but note that everything is flipped for the "ltr" function. for (var i = 0; i < range.set.length; ++i) { var comparators = range.set[i]; var high = null; var low = null; comparators.forEach(function(comparator) { if (comparator.semver === ANY) { comparator = new Comparator('>=0.0.0') } high = high || comparator; low = low || comparator; if (gtfn(comparator.semver, high.semver, loose)) { high = comparator; } else if (ltfn(comparator.semver, low.semver, loose)) { low = comparator; } }); // If the edge version comparator has a operator then our version // isn't outside it if (high.operator === comp || high.operator === ecomp) { return false; } // If the lowest version comparator has an operator and our version // is less than it then it isn't higher than the range if ((!low.operator || low.operator === comp) && ltefn(version, low.semver)) { return false; } else if (low.operator === ecomp && ltfn(version, low.semver)) { return false; } } return true; } exports.prerelease = prerelease; function prerelease(version, loose) { var parsed = parse(version, loose); return (parsed && parsed.prerelease.length) ? parsed.prerelease : null; } |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 39.29% | (33 / 84) | 13.33% | (4 / 30) | 8.33% | (1 / 12) | 39.29% | (33 / 84) | |
| signals.js | 100% | (5 / 5) | 50% | (2 / 4) | 100% | (0 / 0) | 100% | (5 / 5) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18 1 1 1 1 1 1 1 1 1 1 1 1 1 | // Note: since nyc uses this module to output coverage, any lines
// that are in the direct sync flow of nyc's outputCoverage are
// ignored, since we can never get coverage for them.
var assert = require('assert')
var signals = require('./signals.js')
var EE = require('events')
/* istanbul ignore if */
Iif (typeof EE !== 'function') {
EE = EE.EventEmitter
}
var emitter
Iif (process.__signal_exit_emitter__) {
emitter = process.__signal_exit_emitter__
} else {
emitter = process.__signal_exit_emitter__ = new EE()
emitter.count = 0
emitter.emitted = {}
}
// Because this emitter is a global, we have to check to see if a
// previous version of this library failed to enable infinite listeners.
// I know what you're about to say. But literally everything about
// signal-exit is a compromise with evil. Get used to it.
Eif (!emitter.infinite) {
emitter.setMaxListeners(Infinity)
emitter.infinite = true
}
module.exports = function (cb, opts) {
assert.equal(typeof cb, 'function', 'a callback must be provided for exit handler')
if (loaded === false) {
load()
}
var ev = 'exit'
if (opts && opts.alwaysLast) {
ev = 'afterexit'
}
var remove = function () {
emitter.removeListener(ev, cb)
if (emitter.listeners('exit').length === 0 &&
emitter.listeners('afterexit').length === 0) {
unload()
}
}
emitter.on(ev, cb)
return remove
}
module.exports.unload = unload
function unload () {
if (!loaded) {
return
}
loaded = false
signals.forEach(function (sig) {
try {
process.removeListener(sig, sigListeners[sig])
} catch (er) {}
})
process.emit = originalProcessEmit
process.reallyExit = originalProcessReallyExit
emitter.count -= 1
}
function emit (event, code, signal) {
if (emitter.emitted[event]) {
return
}
emitter.emitted[event] = true
emitter.emit(event, code, signal)
}
// { <signal>: <listener fn>, ... }
var sigListeners = {}
signals.forEach(function (sig) {
sigListeners[sig] = function listener () {
// If there are no other listeners, an exit is coming!
// Simplest way: remove us and then re-send the signal.
// We know that this will kill the process, so we can
// safely emit now.
var listeners = process.listeners(sig)
if (listeners.length === emitter.count) {
unload()
emit('exit', null, sig)
/* istanbul ignore next */
emit('afterexit', null, sig)
/* istanbul ignore next */
process.kill(process.pid, sig)
}
}
})
module.exports.signals = function () {
return signals
}
module.exports.load = load
var loaded = false
function load () {
if (loaded) {
return
}
loaded = true
// This is the number of onSignalExit's that are in play.
// It's important so that we can count the correct number of
// listeners on signals, and don't wait for the other one to
// handle it instead of us.
emitter.count += 1
signals = signals.filter(function (sig) {
try {
process.on(sig, sigListeners[sig])
return true
} catch (er) {
return false
}
})
process.emit = processEmit
process.reallyExit = processReallyExit
}
var originalProcessReallyExit = process.reallyExit
function processReallyExit (code) {
process.exitCode = code || 0
emit('exit', process.exitCode, null)
/* istanbul ignore next */
emit('afterexit', process.exitCode, null)
/* istanbul ignore next */
originalProcessReallyExit.call(process, process.exitCode)
}
var originalProcessEmit = process.emit
function processEmit (ev, arg) {
if (ev === 'exit') {
if (arg !== undefined) {
process.exitCode = arg
}
var ret = originalProcessEmit.apply(this, arguments)
emit('exit', process.exitCode, null)
/* istanbul ignore next */
emit('afterexit', process.exitCode, null)
return ret
} else {
return originalProcessEmit.apply(this, arguments)
}
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | 1 1 1 1 1 | // This is not the set of all possible signals.
//
// It IS, however, the set of all signals that trigger
// an exit on either Linux or BSD systems. Linux is a
// superset of the signal names supported on BSD, and
// the unknown signals just fail to register, so we can
// catch that easily enough.
//
// Don't bother with SIGKILL. It's uncatchable, which
// means that we can't fire any callbacks anyway.
//
// If a user does happen to register a handler on a non-
// fatal signal like SIGWINCH or something, and then
// exit, it'll end up firing `process.emit('exit')`, so
// the handler will be fired anyway.
//
// SIGBUS, SIGFPE, SIGSEGV and SIGILL, when not raised
// artificially, inherently leave the process in a
// state from which it is not safe to try and enter JS
// listeners.
module.exports = [
'SIGABRT',
'SIGALRM',
'SIGHUP',
'SIGINT',
'SIGTERM'
]
Eif (process.platform !== 'win32') {
module.exports.push(
'SIGVTALRM',
'SIGXCPU',
'SIGXFSZ',
'SIGUSR2',
'SIGTRAP',
'SIGSYS',
'SIGQUIT',
'SIGIOT'
// should detect profiler and enable/disable accordingly.
// see #21
// 'SIGPROF'
)
}
Eif (process.platform === 'linux') {
module.exports.push(
'SIGIO',
'SIGPOLL',
'SIGPWR',
'SIGSTKFLT',
'SIGUNUSED'
)
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| async-map.js | 9.38% | (3 / 32) | 0% | (0 / 22) | 0% | (0 / 7) | 13.04% | (3 / 23) | |
| bind-actor.js | 18.18% | (2 / 11) | 0% | (0 / 4) | 0% | (0 / 2) | 18.18% | (2 / 11) | |
| chain.js | 25% | (5 / 20) | 0% | (0 / 14) | 0% | (0 / 4) | 26.67% | (4 / 15) | |
| slide.js | 100% | (3 / 3) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (3 / 3) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 1 1 1 |
/*
usage:
// do something to a list of things
asyncMap(myListOfStuff, function (thing, cb) { doSomething(thing.foo, cb) }, cb)
// do more than one thing to each item
asyncMap(list, fooFn, barFn, cb)
*/
module.exports = asyncMap
function asyncMap () {
var steps = Array.prototype.slice.call(arguments)
, list = steps.shift() || []
, cb_ = steps.pop()
if (typeof cb_ !== "function") throw new Error(
"No callback provided to asyncMap")
if (!list) return cb_(null, [])
if (!Array.isArray(list)) list = [list]
var n = steps.length
, data = [] // 2d array
, errState = null
, l = list.length
, a = l * n
if (!a) return cb_(null, [])
function cb (er) {
if (er && !errState) errState = er
var argLen = arguments.length
for (var i = 1; i < argLen; i ++) if (arguments[i] !== undefined) {
data[i - 1] = (data[i - 1] || []).concat(arguments[i])
}
// see if any new things have been added.
if (list.length > l) {
var newList = list.slice(l)
a += (list.length - l) * n
l = list.length
process.nextTick(function () {
newList.forEach(function (ar) {
steps.forEach(function (fn) { fn(ar, cb) })
})
})
}
if (--a === 0) cb_.apply(null, [errState].concat(data))
}
// expect the supplied cb function to be called
// "n" times for each thing in the array.
list.forEach(function (ar) {
steps.forEach(function (fn) { fn(ar, cb) })
})
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 1 1 | module.exports = bindActor function bindActor () { var args = Array.prototype.slice.call (arguments) // jswtf. , obj = null , fn if (typeof args[0] === "object") { obj = args.shift() fn = args.shift() if (typeof fn === "string") fn = obj[ fn ] } else fn = args.shift() return function (cb) { fn.apply(obj, args.concat(cb)) } } |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 1 1 1 1 | module.exports = chain
var bindActor = require("./bind-actor.js")
chain.first = {} ; chain.last = {}
function chain (things, cb) {
var res = []
;(function LOOP (i, len) {
if (i >= len) return cb(null,res)
if (Array.isArray(things[i]))
things[i] = bindActor.apply(null,
things[i].map(function(i){
return (i===chain.first) ? res[0]
: (i===chain.last)
? res[res.length - 1] : i }))
if (!things[i]) return LOOP(i + 1, len)
things[i](function (er, data) {
if (er) return cb(er, res)
if (data !== undefined) res = res.concat(data)
LOOP(i + 1, len)
})
})(0, things.length) }
|
| 1 2 3 4 5 | 1 1 1 | exports.asyncMap = require("./async-map")
exports.bindActor = require("./bind-actor")
exports.chain = require("./chain")
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| source-map.js | 100% | (3 / 3) | 100% | (0 / 0) | 100% | (0 / 0) | 100% | (3 / 3) |
| 1 2 3 4 5 6 7 8 9 10 | 1 1 1 | /*
* Copyright 2009-2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE.txt or:
* http://opensource.org/licenses/BSD-3-Clause
*/
exports.SourceMapGenerator = require('./lib/source-map-generator').SourceMapGenerator;
exports.SourceMapConsumer = require('./lib/source-map-consumer').SourceMapConsumer;
exports.SourceNode = require('./lib/source-node').SourceNode;
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| array-set.js | 31.43% | (11 / 35) | 0% | (0 / 12) | 0% | (0 / 8) | 31.43% | (11 / 35) | |
| base64-vlq.js | 23.08% | (9 / 39) | 0% | (0 / 10) | 0% | (0 / 4) | 23.08% | (9 / 39) | |
| base64.js | 11.11% | (3 / 27) | 0% | (0 / 20) | 0% | (0 / 2) | 11.11% | (3 / 27) | |
| binary-search.js | 13.79% | (4 / 29) | 0% | (0 / 24) | 0% | (0 / 2) | 13.79% | (4 / 29) | |
| mapping-list.js | 28% | (7 / 25) | 0% | (0 / 8) | 0% | (0 / 5) | 28% | (7 / 25) | |
| quick-sort.js | 18.18% | (4 / 22) | 0% | (0 / 4) | 0% | (0 / 4) | 18.18% | (4 / 22) | |
| source-map-consumer.js | 13.62% | (47 / 345) | 0% | (0 / 155) | 0% | (0 / 33) | 13.62% | (47 / 345) | |
| source-map-generator.js | 9.52% | (16 / 168) | 0% | (0 / 111) | 0% | (0 / 15) | 9.52% | (16 / 168) | |
| source-node.js | 11.46% | (18 / 157) | 0% | (0 / 77) | 0% | (0 / 19) | 11.54% | (18 / 156) | |
| util.js | 16.58% | (31 / 187) | 1.52% | (2 / 132) | 6.25% | (1 / 16) | 16.58% | (31 / 187) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | 1 1 1 1 1 1 1 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = require('./util');
var has = Object.prototype.hasOwnProperty;
/**
* A data structure which is a combination of an array and a set. Adding a new
* member is O(1), testing for membership is O(1), and finding the index of an
* element is O(1). Removing elements from the set is not supported. Only
* strings are supported for membership.
*/
function ArraySet() {
this._array = [];
this._set = Object.create(null);
}
/**
* Static method for creating ArraySet instances from an existing array.
*/
ArraySet.fromArray = function ArraySet_fromArray(aArray, aAllowDuplicates) {
var set = new ArraySet();
for (var i = 0, len = aArray.length; i < len; i++) {
set.add(aArray[i], aAllowDuplicates);
}
return set;
};
/**
* Return how many unique items are in this ArraySet. If duplicates have been
* added, than those do not count towards the size.
*
* @returns Number
*/
ArraySet.prototype.size = function ArraySet_size() {
return Object.getOwnPropertyNames(this._set).length;
};
/**
* Add the given string to this set.
*
* @param String aStr
*/
ArraySet.prototype.add = function ArraySet_add(aStr, aAllowDuplicates) {
var sStr = util.toSetString(aStr);
var isDuplicate = has.call(this._set, sStr);
var idx = this._array.length;
if (!isDuplicate || aAllowDuplicates) {
this._array.push(aStr);
}
if (!isDuplicate) {
this._set[sStr] = idx;
}
};
/**
* Is the given string a member of this set?
*
* @param String aStr
*/
ArraySet.prototype.has = function ArraySet_has(aStr) {
var sStr = util.toSetString(aStr);
return has.call(this._set, sStr);
};
/**
* What is the index of the given string in the array?
*
* @param String aStr
*/
ArraySet.prototype.indexOf = function ArraySet_indexOf(aStr) {
var sStr = util.toSetString(aStr);
if (has.call(this._set, sStr)) {
return this._set[sStr];
}
throw new Error('"' + aStr + '" is not in the set.');
};
/**
* What is the element at the given index?
*
* @param Number aIdx
*/
ArraySet.prototype.at = function ArraySet_at(aIdx) {
if (aIdx >= 0 && aIdx < this._array.length) {
return this._array[aIdx];
}
throw new Error('No element indexed by ' + aIdx);
};
/**
* Returns the array representation of this set (which has the proper indices
* indicated by indexOf). Note that this is a copy of the internal array used
* for storing the members so that no one can mess with internal state.
*/
ArraySet.prototype.toArray = function ArraySet_toArray() {
return this._array.slice();
};
exports.ArraySet = ArraySet;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | 1 1 1 1 1 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*
* Based on the Base 64 VLQ implementation in Closure Compiler:
* https://code.google.com/p/closure-compiler/source/browse/trunk/src/com/google/debugging/sourcemap/Base64VLQ.java
*
* Copyright 2011 The Closure Compiler Authors. All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var base64 = require('./base64');
// A single base 64 digit can contain 6 bits of data. For the base 64 variable
// length quantities we use in the source map spec, the first bit is the sign,
// the next four bits are the actual value, and the 6th bit is the
// continuation bit. The continuation bit tells us whether there are more
// digits in this value following this digit.
//
// Continuation
// | Sign
// | |
// V V
// 101011
var VLQ_BASE_SHIFT = 5;
// binary: 100000
var VLQ_BASE = 1 << VLQ_BASE_SHIFT;
// binary: 011111
var VLQ_BASE_MASK = VLQ_BASE - 1;
// binary: 100000
var VLQ_CONTINUATION_BIT = VLQ_BASE;
/**
* Converts from a two-complement value to a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
* 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
*/
function toVLQSigned(aValue) {
return aValue < 0
? ((-aValue) << 1) + 1
: (aValue << 1) + 0;
}
/**
* Converts to a two-complement value from a value where the sign bit is
* placed in the least significant bit. For example, as decimals:
* 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
* 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
*/
function fromVLQSigned(aValue) {
var isNegative = (aValue & 1) === 1;
var shifted = aValue >> 1;
return isNegative
? -shifted
: shifted;
}
/**
* Returns the base 64 VLQ encoded value.
*/
exports.encode = function base64VLQ_encode(aValue) {
var encoded = "";
var digit;
var vlq = toVLQSigned(aValue);
do {
digit = vlq & VLQ_BASE_MASK;
vlq >>>= VLQ_BASE_SHIFT;
if (vlq > 0) {
// There are still more digits in this value, so we must make sure the
// continuation bit is marked.
digit |= VLQ_CONTINUATION_BIT;
}
encoded += base64.encode(digit);
} while (vlq > 0);
return encoded;
};
/**
* Decodes the next base 64 VLQ value from the given string and returns the
* value and the rest of the string via the out parameter.
*/
exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) {
var strLen = aStr.length;
var result = 0;
var shift = 0;
var continuation, digit;
do {
if (aIndex >= strLen) {
throw new Error("Expected more digits in base 64 VLQ value.");
}
digit = base64.decode(aStr.charCodeAt(aIndex++));
if (digit === -1) {
throw new Error("Invalid base64 digit: " + aStr.charAt(aIndex - 1));
}
continuation = !!(digit & VLQ_CONTINUATION_BIT);
digit &= VLQ_BASE_MASK;
result = result + (digit << shift);
shift += VLQ_BASE_SHIFT;
} while (continuation);
aOutParam.value = fromVLQSigned(result);
aOutParam.rest = aIndex;
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var intToCharMap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split('');
/**
* Encode an integer in the range of 0 to 63 to a single base 64 digit.
*/
exports.encode = function (number) {
if (0 <= number && number < intToCharMap.length) {
return intToCharMap[number];
}
throw new TypeError("Must be between 0 and 63: " + number);
};
/**
* Decode a single base 64 character code digit to an integer. Returns -1 on
* failure.
*/
exports.decode = function (charCode) {
var bigA = 65; // 'A'
var bigZ = 90; // 'Z'
var littleA = 97; // 'a'
var littleZ = 122; // 'z'
var zero = 48; // '0'
var nine = 57; // '9'
var plus = 43; // '+'
var slash = 47; // '/'
var littleOffset = 26;
var numberOffset = 52;
// 0 - 25: ABCDEFGHIJKLMNOPQRSTUVWXYZ
if (bigA <= charCode && charCode <= bigZ) {
return (charCode - bigA);
}
// 26 - 51: abcdefghijklmnopqrstuvwxyz
if (littleA <= charCode && charCode <= littleZ) {
return (charCode - littleA + littleOffset);
}
// 52 - 61: 0123456789
if (zero <= charCode && charCode <= nine) {
return (charCode - zero + numberOffset);
}
// 62: +
if (charCode == plus) {
return 62;
}
// 63: /
if (charCode == slash) {
return 63;
}
// Invalid base64 digit.
return -1;
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ exports.GREATEST_LOWER_BOUND = 1; exports.LEAST_UPPER_BOUND = 2; /** * Recursive implementation of binary search. * * @param aLow Indices here and lower do not contain the needle. * @param aHigh Indices here and higher do not contain the needle. * @param aNeedle The element being searched for. * @param aHaystack The non-empty array being searched. * @param aCompare Function which takes two elements and returns -1, 0, or 1. * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the * closest element that is smaller than or greater than the one we are * searching for, respectively, if the exact element cannot be found. */ function recursiveSearch(aLow, aHigh, aNeedle, aHaystack, aCompare, aBias) { // This function terminates when one of the following is true: // // 1. We find the exact element we are looking for. // // 2. We did not find the exact element, but we can return the index of // the next-closest element. // // 3. We did not find the exact element, and there is no next-closest // element than the one we are searching for, so we return -1. var mid = Math.floor((aHigh - aLow) / 2) + aLow; var cmp = aCompare(aNeedle, aHaystack[mid], true); if (cmp === 0) { // Found the element we are looking for. return mid; } else if (cmp > 0) { // Our needle is greater than aHaystack[mid]. if (aHigh - mid > 1) { // The element is in the upper half. return recursiveSearch(mid, aHigh, aNeedle, aHaystack, aCompare, aBias); } // The exact needle element was not found in this haystack. Determine if // we are in termination case (3) or (2) and return the appropriate thing. if (aBias == exports.LEAST_UPPER_BOUND) { return aHigh < aHaystack.length ? aHigh : -1; } else { return mid; } } else { // Our needle is less than aHaystack[mid]. if (mid - aLow > 1) { // The element is in the lower half. return recursiveSearch(aLow, mid, aNeedle, aHaystack, aCompare, aBias); } // we are in termination case (3) or (2) and return the appropriate thing. if (aBias == exports.LEAST_UPPER_BOUND) { return mid; } else { return aLow < 0 ? -1 : aLow; } } } /** * This is an implementation of binary search which will always try and return * the index of the closest element if there is no exact hit. This is because * mappings between original and generated line/col pairs are single points, * and there is an implicit region between each of them, so a miss just means * that you aren't on the very start of a region. * * @param aNeedle The element you are looking for. * @param aHaystack The array that is being searched. * @param aCompare A function which takes the needle and an element in the * array and returns -1, 0, or 1 depending on whether the needle is less * than, equal to, or greater than the element, respectively. * @param aBias Either 'binarySearch.GREATEST_LOWER_BOUND' or * 'binarySearch.LEAST_UPPER_BOUND'. Specifies whether to return the * closest element that is smaller than or greater than the one we are * searching for, respectively, if the exact element cannot be found. * Defaults to 'binarySearch.GREATEST_LOWER_BOUND'. */ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { if (aHaystack.length === 0) { return -1; } var index = recursiveSearch(-1, aHaystack.length, aNeedle, aHaystack, aCompare, aBias || exports.GREATEST_LOWER_BOUND); if (index < 0) { return -1; } // We have found either the exact element, or the next-closest element than // the one we are searching for. However, there may be more than one such // element. Make sure we always return the smallest of these. while (index - 1 >= 0) { if (aCompare(aHaystack[index], aHaystack[index - 1], true) !== 0) { break; } --index; } return index; }; |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | 1 1 1 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2014 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = require('./util');
/**
* Determine whether mappingB is after mappingA with respect to generated
* position.
*/
function generatedPositionAfter(mappingA, mappingB) {
// Optimized for most common case
var lineA = mappingA.generatedLine;
var lineB = mappingB.generatedLine;
var columnA = mappingA.generatedColumn;
var columnB = mappingB.generatedColumn;
return lineB > lineA || lineB == lineA && columnB >= columnA ||
util.compareByGeneratedPositionsInflated(mappingA, mappingB) <= 0;
}
/**
* A data structure to provide a sorted view of accumulated mappings in a
* performance conscious manner. It trades a neglibable overhead in general
* case for a large speedup in case of mappings being added in order.
*/
function MappingList() {
this._array = [];
this._sorted = true;
// Serves as infimum
this._last = {generatedLine: -1, generatedColumn: 0};
}
/**
* Iterate through internal items. This method takes the same arguments that
* `Array.prototype.forEach` takes.
*
* NOTE: The order of the mappings is NOT guaranteed.
*/
MappingList.prototype.unsortedForEach =
function MappingList_forEach(aCallback, aThisArg) {
this._array.forEach(aCallback, aThisArg);
};
/**
* Add the given source mapping.
*
* @param Object aMapping
*/
MappingList.prototype.add = function MappingList_add(aMapping) {
if (generatedPositionAfter(this._last, aMapping)) {
this._last = aMapping;
this._array.push(aMapping);
} else {
this._sorted = false;
this._array.push(aMapping);
}
};
/**
* Returns the flat, sorted array of mappings. The mappings are sorted by
* generated position.
*
* WARNING: This method returns internal data without copying, for
* performance. The return value must NOT be mutated, and should be treated as
* an immutable borrow. If you want to take ownership, you must make your own
* copy.
*/
MappingList.prototype.toArray = function MappingList_toArray() {
if (!this._sorted) {
this._array.sort(util.compareByGeneratedPositionsInflated);
this._sorted = true;
}
return this._array;
};
exports.MappingList = MappingList;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
// It turns out that some (most?) JavaScript engines don't self-host
// `Array.prototype.sort`. This makes sense because C++ will likely remain
// faster than JS when doing raw CPU-intensive sorting. However, when using a
// custom comparator function, calling back and forth between the VM's C++ and
// JIT'd JS is rather slow *and* loses JIT type information, resulting in
// worse generated code for the comparator function than would be optimal. In
// fact, when sorting with a comparator, these costs outweigh the benefits of
// sorting in C++. By using our own JS-implemented Quick Sort (below), we get
// a ~3500ms mean speed-up in `bench/bench.html`.
/**
* Swap the elements indexed by `x` and `y` in the array `ary`.
*
* @param {Array} ary
* The array.
* @param {Number} x
* The index of the first item.
* @param {Number} y
* The index of the second item.
*/
function swap(ary, x, y) {
var temp = ary[x];
ary[x] = ary[y];
ary[y] = temp;
}
/**
* Returns a random integer within the range `low .. high` inclusive.
*
* @param {Number} low
* The lower bound on the range.
* @param {Number} high
* The upper bound on the range.
*/
function randomIntInRange(low, high) {
return Math.round(low + (Math.random() * (high - low)));
}
/**
* The Quick Sort algorithm.
*
* @param {Array} ary
* An array to sort.
* @param {function} comparator
* Function to use to compare two items.
* @param {Number} p
* Start index of the array
* @param {Number} r
* End index of the array
*/
function doQuickSort(ary, comparator, p, r) {
// If our lower bound is less than our upper bound, we (1) partition the
// array into two pieces and (2) recurse on each half. If it is not, this is
// the empty array and our base case.
if (p < r) {
// (1) Partitioning.
//
// The partitioning chooses a pivot between `p` and `r` and moves all
// elements that are less than or equal to the pivot to the before it, and
// all the elements that are greater than it after it. The effect is that
// once partition is done, the pivot is in the exact place it will be when
// the array is put in sorted order, and it will not need to be moved
// again. This runs in O(n) time.
// Always choose a random pivot so that an input array which is reverse
// sorted does not cause O(n^2) running time.
var pivotIndex = randomIntInRange(p, r);
var i = p - 1;
swap(ary, pivotIndex, r);
var pivot = ary[r];
// Immediately after `j` is incremented in this loop, the following hold
// true:
//
// * Every element in `ary[p .. i]` is less than or equal to the pivot.
//
// * Every element in `ary[i+1 .. j-1]` is greater than the pivot.
for (var j = p; j < r; j++) {
if (comparator(ary[j], pivot) <= 0) {
i += 1;
swap(ary, i, j);
}
}
swap(ary, i + 1, j);
var q = i + 1;
// (2) Recurse on each half.
doQuickSort(ary, comparator, p, q - 1);
doQuickSort(ary, comparator, q + 1, r);
}
}
/**
* Sort the given array in-place with the given comparator function.
*
* @param {Array} ary
* An array to sort.
* @param {function} comparator
* Function to use to compare two items.
*/
exports.quickSort = function (ary, comparator) {
doQuickSort(ary, comparator, 0, ary.length - 1);
};
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var util = require('./util');
var binarySearch = require('./binary-search');
var ArraySet = require('./array-set').ArraySet;
var base64VLQ = require('./base64-vlq');
var quickSort = require('./quick-sort').quickSort;
function SourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
}
return sourceMap.sections != null
? new IndexedSourceMapConsumer(sourceMap)
: new BasicSourceMapConsumer(sourceMap);
}
SourceMapConsumer.fromSourceMap = function(aSourceMap) {
return BasicSourceMapConsumer.fromSourceMap(aSourceMap);
}
/**
* The version of the source mapping spec that we are consuming.
*/
SourceMapConsumer.prototype._version = 3;
// `__generatedMappings` and `__originalMappings` are arrays that hold the
// parsed mapping coordinates from the source map's "mappings" attribute. They
// are lazily instantiated, accessed via the `_generatedMappings` and
// `_originalMappings` getters respectively, and we only parse the mappings
// and create these arrays once queried for a source location. We jump through
// these hoops because there can be many thousands of mappings, and parsing
// them is expensive, so we only want to do it if we must.
//
// Each object in the arrays is of the form:
//
// {
// generatedLine: The line number in the generated code,
// generatedColumn: The column number in the generated code,
// source: The path to the original source file that generated this
// chunk of code,
// originalLine: The line number in the original source that
// corresponds to this chunk of generated code,
// originalColumn: The column number in the original source that
// corresponds to this chunk of generated code,
// name: The name of the original symbol which generated this chunk of
// code.
// }
//
// All properties except for `generatedLine` and `generatedColumn` can be
// `null`.
//
// `_generatedMappings` is ordered by the generated positions.
//
// `_originalMappings` is ordered by the original positions.
SourceMapConsumer.prototype.__generatedMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_generatedMappings', {
get: function () {
if (!this.__generatedMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
}
return this.__generatedMappings;
}
});
SourceMapConsumer.prototype.__originalMappings = null;
Object.defineProperty(SourceMapConsumer.prototype, '_originalMappings', {
get: function () {
if (!this.__originalMappings) {
this._parseMappings(this._mappings, this.sourceRoot);
}
return this.__originalMappings;
}
});
SourceMapConsumer.prototype._charIsMappingSeparator =
function SourceMapConsumer_charIsMappingSeparator(aStr, index) {
var c = aStr.charAt(index);
return c === ";" || c === ",";
};
/**
* Parse the mappings in a string in to a data structure which we can easily
* query (the ordered arrays in the `this.__generatedMappings` and
* `this.__originalMappings` properties).
*/
SourceMapConsumer.prototype._parseMappings =
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
throw new Error("Subclasses must implement _parseMappings");
};
SourceMapConsumer.GENERATED_ORDER = 1;
SourceMapConsumer.ORIGINAL_ORDER = 2;
SourceMapConsumer.GREATEST_LOWER_BOUND = 1;
SourceMapConsumer.LEAST_UPPER_BOUND = 2;
/**
* Iterate over each mapping between an original source/line/column and a
* generated line/column in this source map.
*
* @param Function aCallback
* The function that is called with each mapping.
* @param Object aContext
* Optional. If specified, this object will be the value of `this` every
* time that `aCallback` is called.
* @param aOrder
* Either `SourceMapConsumer.GENERATED_ORDER` or
* `SourceMapConsumer.ORIGINAL_ORDER`. Specifies whether you want to
* iterate over the mappings sorted by the generated file's line/column
* order or the original's source/line/column order, respectively. Defaults to
* `SourceMapConsumer.GENERATED_ORDER`.
*/
SourceMapConsumer.prototype.eachMapping =
function SourceMapConsumer_eachMapping(aCallback, aContext, aOrder) {
var context = aContext || null;
var order = aOrder || SourceMapConsumer.GENERATED_ORDER;
var mappings;
switch (order) {
case SourceMapConsumer.GENERATED_ORDER:
mappings = this._generatedMappings;
break;
case SourceMapConsumer.ORIGINAL_ORDER:
mappings = this._originalMappings;
break;
default:
throw new Error("Unknown order of iteration.");
}
var sourceRoot = this.sourceRoot;
mappings.map(function (mapping) {
var source = mapping.source === null ? null : this._sources.at(mapping.source);
if (source != null && sourceRoot != null) {
source = util.join(sourceRoot, source);
}
return {
source: source,
generatedLine: mapping.generatedLine,
generatedColumn: mapping.generatedColumn,
originalLine: mapping.originalLine,
originalColumn: mapping.originalColumn,
name: mapping.name === null ? null : this._names.at(mapping.name)
};
}, this).forEach(aCallback, context);
};
/**
* Returns all generated line and column information for the original source,
* line, and column provided. If no column is provided, returns all mappings
* corresponding to a either the line we are searching for or the next
* closest line that has any mappings. Otherwise, returns all mappings
* corresponding to the given line and either the column we are searching for
* or the next closest column that has any offsets.
*
* The only argument is an object with the following properties:
*
* - source: The filename of the original source.
* - line: The line number in the original source.
* - column: Optional. the column number in the original source.
*
* and an array of objects is returned, each with the following properties:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
SourceMapConsumer.prototype.allGeneratedPositionsFor =
function SourceMapConsumer_allGeneratedPositionsFor(aArgs) {
var line = util.getArg(aArgs, 'line');
// When there is no exact match, BasicSourceMapConsumer.prototype._findMapping
// returns the index of the closest mapping less than the needle. By
// setting needle.originalColumn to 0, we thus find the last mapping for
// the given line, provided such a mapping exists.
var needle = {
source: util.getArg(aArgs, 'source'),
originalLine: line,
originalColumn: util.getArg(aArgs, 'column', 0)
};
if (this.sourceRoot != null) {
needle.source = util.relative(this.sourceRoot, needle.source);
}
if (!this._sources.has(needle.source)) {
return [];
}
needle.source = this._sources.indexOf(needle.source);
var mappings = [];
var index = this._findMapping(needle,
this._originalMappings,
"originalLine",
"originalColumn",
util.compareByOriginalPositions,
binarySearch.LEAST_UPPER_BOUND);
if (index >= 0) {
var mapping = this._originalMappings[index];
if (aArgs.column === undefined) {
var originalLine = mapping.originalLine;
// Iterate until either we run out of mappings, or we run into
// a mapping for a different line than the one we found. Since
// mappings are sorted, this is guaranteed to find all mappings for
// the line we found.
while (mapping && mapping.originalLine === originalLine) {
mappings.push({
line: util.getArg(mapping, 'generatedLine', null),
column: util.getArg(mapping, 'generatedColumn', null),
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
});
mapping = this._originalMappings[++index];
}
} else {
var originalColumn = mapping.originalColumn;
// Iterate until either we run out of mappings, or we run into
// a mapping for a different line than the one we were searching for.
// Since mappings are sorted, this is guaranteed to find all mappings for
// the line we are searching for.
while (mapping &&
mapping.originalLine === line &&
mapping.originalColumn == originalColumn) {
mappings.push({
line: util.getArg(mapping, 'generatedLine', null),
column: util.getArg(mapping, 'generatedColumn', null),
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
});
mapping = this._originalMappings[++index];
}
}
}
return mappings;
};
exports.SourceMapConsumer = SourceMapConsumer;
/**
* A BasicSourceMapConsumer instance represents a parsed source map which we can
* query for information about the original file positions by giving it a file
* position in the generated source.
*
* The only parameter is the raw source map (either as a JSON string, or
* already parsed to an object). According to the spec, source maps have the
* following attributes:
*
* - version: Which version of the source map spec this map is following.
* - sources: An array of URLs to the original source files.
* - names: An array of identifiers which can be referrenced by individual mappings.
* - sourceRoot: Optional. The URL root from which all sources are relative.
* - sourcesContent: Optional. An array of contents of the original source files.
* - mappings: A string of base64 VLQs which contain the actual mappings.
* - file: Optional. The generated file this source map is associated with.
*
* Here is an example source map, taken from the source map spec[0]:
*
* {
* version : 3,
* file: "out.js",
* sourceRoot : "",
* sources: ["foo.js", "bar.js"],
* names: ["src", "maps", "are", "fun"],
* mappings: "AA,AB;;ABCDE;"
* }
*
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
*/
function BasicSourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
}
var version = util.getArg(sourceMap, 'version');
var sources = util.getArg(sourceMap, 'sources');
// Sass 3.3 leaves out the 'names' array, so we deviate from the spec (which
// requires the array) to play nice here.
var names = util.getArg(sourceMap, 'names', []);
var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
var sourcesContent = util.getArg(sourceMap, 'sourcesContent', null);
var mappings = util.getArg(sourceMap, 'mappings');
var file = util.getArg(sourceMap, 'file', null);
// Once again, Sass deviates from the spec and supplies the version as a
// string rather than a number, so we use loose equality checking here.
if (version != this._version) {
throw new Error('Unsupported version: ' + version);
}
sources = sources
.map(String)
// Some source maps produce relative source paths like "./foo.js" instead of
// "foo.js". Normalize these first so that future comparisons will succeed.
// See bugzil.la/1090768.
.map(util.normalize)
// Always ensure that absolute sources are internally stored relative to
// the source root, if the source root is absolute. Not doing this would
// be particularly problematic when the source root is a prefix of the
// source (valid, but why??). See github issue #199 and bugzil.la/1188982.
.map(function (source) {
return sourceRoot && util.isAbsolute(sourceRoot) && util.isAbsolute(source)
? util.relative(sourceRoot, source)
: source;
});
// Pass `true` below to allow duplicate names and sources. While source maps
// are intended to be compressed and deduplicated, the TypeScript compiler
// sometimes generates source maps with duplicates in them. See Github issue
// #72 and bugzil.la/889492.
this._names = ArraySet.fromArray(names.map(String), true);
this._sources = ArraySet.fromArray(sources, true);
this.sourceRoot = sourceRoot;
this.sourcesContent = sourcesContent;
this._mappings = mappings;
this.file = file;
}
BasicSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
BasicSourceMapConsumer.prototype.consumer = SourceMapConsumer;
/**
* Create a BasicSourceMapConsumer from a SourceMapGenerator.
*
* @param SourceMapGenerator aSourceMap
* The source map that will be consumed.
* @returns BasicSourceMapConsumer
*/
BasicSourceMapConsumer.fromSourceMap =
function SourceMapConsumer_fromSourceMap(aSourceMap) {
var smc = Object.create(BasicSourceMapConsumer.prototype);
var names = smc._names = ArraySet.fromArray(aSourceMap._names.toArray(), true);
var sources = smc._sources = ArraySet.fromArray(aSourceMap._sources.toArray(), true);
smc.sourceRoot = aSourceMap._sourceRoot;
smc.sourcesContent = aSourceMap._generateSourcesContent(smc._sources.toArray(),
smc.sourceRoot);
smc.file = aSourceMap._file;
// Because we are modifying the entries (by converting string sources and
// names to indices into the sources and names ArraySets), we have to make
// a copy of the entry or else bad things happen. Shared mutable state
// strikes again! See github issue #191.
var generatedMappings = aSourceMap._mappings.toArray().slice();
var destGeneratedMappings = smc.__generatedMappings = [];
var destOriginalMappings = smc.__originalMappings = [];
for (var i = 0, length = generatedMappings.length; i < length; i++) {
var srcMapping = generatedMappings[i];
var destMapping = new Mapping;
destMapping.generatedLine = srcMapping.generatedLine;
destMapping.generatedColumn = srcMapping.generatedColumn;
if (srcMapping.source) {
destMapping.source = sources.indexOf(srcMapping.source);
destMapping.originalLine = srcMapping.originalLine;
destMapping.originalColumn = srcMapping.originalColumn;
if (srcMapping.name) {
destMapping.name = names.indexOf(srcMapping.name);
}
destOriginalMappings.push(destMapping);
}
destGeneratedMappings.push(destMapping);
}
quickSort(smc.__originalMappings, util.compareByOriginalPositions);
return smc;
};
/**
* The version of the source mapping spec that we are consuming.
*/
BasicSourceMapConsumer.prototype._version = 3;
/**
* The list of original sources.
*/
Object.defineProperty(BasicSourceMapConsumer.prototype, 'sources', {
get: function () {
return this._sources.toArray().map(function (s) {
return this.sourceRoot != null ? util.join(this.sourceRoot, s) : s;
}, this);
}
});
/**
* Provide the JIT with a nice shape / hidden class.
*/
function Mapping() {
this.generatedLine = 0;
this.generatedColumn = 0;
this.source = null;
this.originalLine = null;
this.originalColumn = null;
this.name = null;
}
/**
* Parse the mappings in a string in to a data structure which we can easily
* query (the ordered arrays in the `this.__generatedMappings` and
* `this.__originalMappings` properties).
*/
BasicSourceMapConsumer.prototype._parseMappings =
function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
var generatedLine = 1;
var previousGeneratedColumn = 0;
var previousOriginalLine = 0;
var previousOriginalColumn = 0;
var previousSource = 0;
var previousName = 0;
var length = aStr.length;
var index = 0;
var cachedSegments = {};
var temp = {};
var originalMappings = [];
var generatedMappings = [];
var mapping, str, segment, end, value;
while (index < length) {
if (aStr.charAt(index) === ';') {
generatedLine++;
index++;
previousGeneratedColumn = 0;
}
else if (aStr.charAt(index) === ',') {
index++;
}
else {
mapping = new Mapping();
mapping.generatedLine = generatedLine;
// Because each offset is encoded relative to the previous one,
// many segments often have the same encoding. We can exploit this
// fact by caching the parsed variable length fields of each segment,
// allowing us to avoid a second parse if we encounter the same
// segment again.
for (end = index; end < length; end++) {
if (this._charIsMappingSeparator(aStr, end)) {
break;
}
}
str = aStr.slice(index, end);
segment = cachedSegments[str];
if (segment) {
index += str.length;
} else {
segment = [];
while (index < end) {
base64VLQ.decode(aStr, index, temp);
value = temp.value;
index = temp.rest;
segment.push(value);
}
if (segment.length === 2) {
throw new Error('Found a source, but no line and column');
}
if (segment.length === 3) {
throw new Error('Found a source and line, but no column');
}
cachedSegments[str] = segment;
}
// Generated column.
mapping.generatedColumn = previousGeneratedColumn + segment[0];
previousGeneratedColumn = mapping.generatedColumn;
if (segment.length > 1) {
// Original source.
mapping.source = previousSource + segment[1];
previousSource += segment[1];
// Original line.
mapping.originalLine = previousOriginalLine + segment[2];
previousOriginalLine = mapping.originalLine;
// Lines are stored 0-based
mapping.originalLine += 1;
// Original column.
mapping.originalColumn = previousOriginalColumn + segment[3];
previousOriginalColumn = mapping.originalColumn;
if (segment.length > 4) {
// Original name.
mapping.name = previousName + segment[4];
previousName += segment[4];
}
}
generatedMappings.push(mapping);
if (typeof mapping.originalLine === 'number') {
originalMappings.push(mapping);
}
}
}
quickSort(generatedMappings, util.compareByGeneratedPositionsDeflated);
this.__generatedMappings = generatedMappings;
quickSort(originalMappings, util.compareByOriginalPositions);
this.__originalMappings = originalMappings;
};
/**
* Find the mapping that best matches the hypothetical "needle" mapping that
* we are searching for in the given "haystack" of mappings.
*/
BasicSourceMapConsumer.prototype._findMapping =
function SourceMapConsumer_findMapping(aNeedle, aMappings, aLineName,
aColumnName, aComparator, aBias) {
// To return the position we are searching for, we must first find the
// mapping for the given position and then return the opposite position it
// points to. Because the mappings are sorted, we can use binary search to
// find the best mapping.
if (aNeedle[aLineName] <= 0) {
throw new TypeError('Line must be greater than or equal to 1, got '
+ aNeedle[aLineName]);
}
if (aNeedle[aColumnName] < 0) {
throw new TypeError('Column must be greater than or equal to 0, got '
+ aNeedle[aColumnName]);
}
return binarySearch.search(aNeedle, aMappings, aComparator, aBias);
};
/**
* Compute the last column for each generated mapping. The last column is
* inclusive.
*/
BasicSourceMapConsumer.prototype.computeColumnSpans =
function SourceMapConsumer_computeColumnSpans() {
for (var index = 0; index < this._generatedMappings.length; ++index) {
var mapping = this._generatedMappings[index];
// Mappings do not contain a field for the last generated columnt. We
// can come up with an optimistic estimate, however, by assuming that
// mappings are contiguous (i.e. given two consecutive mappings, the
// first mapping ends where the second one starts).
if (index + 1 < this._generatedMappings.length) {
var nextMapping = this._generatedMappings[index + 1];
if (mapping.generatedLine === nextMapping.generatedLine) {
mapping.lastGeneratedColumn = nextMapping.generatedColumn - 1;
continue;
}
}
// The last mapping for each line spans the entire line.
mapping.lastGeneratedColumn = Infinity;
}
};
/**
* Returns the original source, line, and column information for the generated
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
* - line: The line number in the generated source.
* - column: The column number in the generated source.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
* searching for, respectively, if the exact element cannot be found.
* Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
*
* and an object is returned with the following properties:
*
* - source: The original source file, or null.
* - line: The line number in the original source, or null.
* - column: The column number in the original source, or null.
* - name: The original identifier, or null.
*/
BasicSourceMapConsumer.prototype.originalPositionFor =
function SourceMapConsumer_originalPositionFor(aArgs) {
var needle = {
generatedLine: util.getArg(aArgs, 'line'),
generatedColumn: util.getArg(aArgs, 'column')
};
var index = this._findMapping(
needle,
this._generatedMappings,
"generatedLine",
"generatedColumn",
util.compareByGeneratedPositionsDeflated,
util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
);
if (index >= 0) {
var mapping = this._generatedMappings[index];
if (mapping.generatedLine === needle.generatedLine) {
var source = util.getArg(mapping, 'source', null);
if (source !== null) {
source = this._sources.at(source);
if (this.sourceRoot != null) {
source = util.join(this.sourceRoot, source);
}
}
var name = util.getArg(mapping, 'name', null);
if (name !== null) {
name = this._names.at(name);
}
return {
source: source,
line: util.getArg(mapping, 'originalLine', null),
column: util.getArg(mapping, 'originalColumn', null),
name: name
};
}
}
return {
source: null,
line: null,
column: null,
name: null
};
};
/**
* Return true if we have the source content for every source in the source
* map, false otherwise.
*/
BasicSourceMapConsumer.prototype.hasContentsOfAllSources =
function BasicSourceMapConsumer_hasContentsOfAllSources() {
if (!this.sourcesContent) {
return false;
}
return this.sourcesContent.length >= this._sources.size() &&
!this.sourcesContent.some(function (sc) { return sc == null; });
};
/**
* Returns the original source content. The only argument is the url of the
* original source file. Returns null if no original source content is
* available.
*/
BasicSourceMapConsumer.prototype.sourceContentFor =
function SourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
if (!this.sourcesContent) {
return null;
}
if (this.sourceRoot != null) {
aSource = util.relative(this.sourceRoot, aSource);
}
if (this._sources.has(aSource)) {
return this.sourcesContent[this._sources.indexOf(aSource)];
}
var url;
if (this.sourceRoot != null
&& (url = util.urlParse(this.sourceRoot))) {
// XXX: file:// URIs and absolute paths lead to unexpected behavior for
// many users. We can help them out when they expect file:// URIs to
// behave like it would if they were running a local HTTP server. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=885597.
var fileUriAbsPath = aSource.replace(/^file:\/\//, "");
if (url.scheme == "file"
&& this._sources.has(fileUriAbsPath)) {
return this.sourcesContent[this._sources.indexOf(fileUriAbsPath)]
}
if ((!url.path || url.path == "/")
&& this._sources.has("/" + aSource)) {
return this.sourcesContent[this._sources.indexOf("/" + aSource)];
}
}
// This function is used recursively from
// IndexedSourceMapConsumer.prototype.sourceContentFor. In that case, we
// don't want to throw if we can't find the source - we just want to
// return null, so we provide a flag to exit gracefully.
if (nullOnMissing) {
return null;
}
else {
throw new Error('"' + aSource + '" is not in the SourceMap.');
}
};
/**
* Returns the generated line and column information for the original source,
* line, and column positions provided. The only argument is an object with
* the following properties:
*
* - source: The filename of the original source.
* - line: The line number in the original source.
* - column: The column number in the original source.
* - bias: Either 'SourceMapConsumer.GREATEST_LOWER_BOUND' or
* 'SourceMapConsumer.LEAST_UPPER_BOUND'. Specifies whether to return the
* closest element that is smaller than or greater than the one we are
* searching for, respectively, if the exact element cannot be found.
* Defaults to 'SourceMapConsumer.GREATEST_LOWER_BOUND'.
*
* and an object is returned with the following properties:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
BasicSourceMapConsumer.prototype.generatedPositionFor =
function SourceMapConsumer_generatedPositionFor(aArgs) {
var source = util.getArg(aArgs, 'source');
if (this.sourceRoot != null) {
source = util.relative(this.sourceRoot, source);
}
if (!this._sources.has(source)) {
return {
line: null,
column: null,
lastColumn: null
};
}
source = this._sources.indexOf(source);
var needle = {
source: source,
originalLine: util.getArg(aArgs, 'line'),
originalColumn: util.getArg(aArgs, 'column')
};
var index = this._findMapping(
needle,
this._originalMappings,
"originalLine",
"originalColumn",
util.compareByOriginalPositions,
util.getArg(aArgs, 'bias', SourceMapConsumer.GREATEST_LOWER_BOUND)
);
if (index >= 0) {
var mapping = this._originalMappings[index];
if (mapping.source === needle.source) {
return {
line: util.getArg(mapping, 'generatedLine', null),
column: util.getArg(mapping, 'generatedColumn', null),
lastColumn: util.getArg(mapping, 'lastGeneratedColumn', null)
};
}
}
return {
line: null,
column: null,
lastColumn: null
};
};
exports.BasicSourceMapConsumer = BasicSourceMapConsumer;
/**
* An IndexedSourceMapConsumer instance represents a parsed source map which
* we can query for information. It differs from BasicSourceMapConsumer in
* that it takes "indexed" source maps (i.e. ones with a "sections" field) as
* input.
*
* The only parameter is a raw source map (either as a JSON string, or already
* parsed to an object). According to the spec for indexed source maps, they
* have the following attributes:
*
* - version: Which version of the source map spec this map is following.
* - file: Optional. The generated file this source map is associated with.
* - sections: A list of section definitions.
*
* Each value under the "sections" field has two fields:
* - offset: The offset into the original specified at which this section
* begins to apply, defined as an object with a "line" and "column"
* field.
* - map: A source map definition. This source map could also be indexed,
* but doesn't have to be.
*
* Instead of the "map" field, it's also possible to have a "url" field
* specifying a URL to retrieve a source map from, but that's currently
* unsupported.
*
* Here's an example source map, taken from the source map spec[0], but
* modified to omit a section which uses the "url" field.
*
* {
* version : 3,
* file: "app.js",
* sections: [{
* offset: {line:100, column:10},
* map: {
* version : 3,
* file: "section.js",
* sources: ["foo.js", "bar.js"],
* names: ["src", "maps", "are", "fun"],
* mappings: "AAAA,E;;ABCDE;"
* }
* }],
* }
*
* [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt
*/
function IndexedSourceMapConsumer(aSourceMap) {
var sourceMap = aSourceMap;
if (typeof aSourceMap === 'string') {
sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
}
var version = util.getArg(sourceMap, 'version');
var sections = util.getArg(sourceMap, 'sections');
if (version != this._version) {
throw new Error('Unsupported version: ' + version);
}
this._sources = new ArraySet();
this._names = new ArraySet();
var lastOffset = {
line: -1,
column: 0
};
this._sections = sections.map(function (s) {
if (s.url) {
// The url field will require support for asynchronicity.
// See https://github.com/mozilla/source-map/issues/16
throw new Error('Support for url field in sections not implemented.');
}
var offset = util.getArg(s, 'offset');
var offsetLine = util.getArg(offset, 'line');
var offsetColumn = util.getArg(offset, 'column');
if (offsetLine < lastOffset.line ||
(offsetLine === lastOffset.line && offsetColumn < lastOffset.column)) {
throw new Error('Section offsets must be ordered and non-overlapping.');
}
lastOffset = offset;
return {
generatedOffset: {
// The offset fields are 0-based, but we use 1-based indices when
// encoding/decoding from VLQ.
generatedLine: offsetLine + 1,
generatedColumn: offsetColumn + 1
},
consumer: new SourceMapConsumer(util.getArg(s, 'map'))
}
});
}
IndexedSourceMapConsumer.prototype = Object.create(SourceMapConsumer.prototype);
IndexedSourceMapConsumer.prototype.constructor = SourceMapConsumer;
/**
* The version of the source mapping spec that we are consuming.
*/
IndexedSourceMapConsumer.prototype._version = 3;
/**
* The list of original sources.
*/
Object.defineProperty(IndexedSourceMapConsumer.prototype, 'sources', {
get: function () {
var sources = [];
for (var i = 0; i < this._sections.length; i++) {
for (var j = 0; j < this._sections[i].consumer.sources.length; j++) {
sources.push(this._sections[i].consumer.sources[j]);
}
}
return sources;
}
});
/**
* Returns the original source, line, and column information for the generated
* source's line and column positions provided. The only argument is an object
* with the following properties:
*
* - line: The line number in the generated source.
* - column: The column number in the generated source.
*
* and an object is returned with the following properties:
*
* - source: The original source file, or null.
* - line: The line number in the original source, or null.
* - column: The column number in the original source, or null.
* - name: The original identifier, or null.
*/
IndexedSourceMapConsumer.prototype.originalPositionFor =
function IndexedSourceMapConsumer_originalPositionFor(aArgs) {
var needle = {
generatedLine: util.getArg(aArgs, 'line'),
generatedColumn: util.getArg(aArgs, 'column')
};
// Find the section containing the generated position we're trying to map
// to an original position.
var sectionIndex = binarySearch.search(needle, this._sections,
function(needle, section) {
var cmp = needle.generatedLine - section.generatedOffset.generatedLine;
if (cmp) {
return cmp;
}
return (needle.generatedColumn -
section.generatedOffset.generatedColumn);
});
var section = this._sections[sectionIndex];
if (!section) {
return {
source: null,
line: null,
column: null,
name: null
};
}
return section.consumer.originalPositionFor({
line: needle.generatedLine -
(section.generatedOffset.generatedLine - 1),
column: needle.generatedColumn -
(section.generatedOffset.generatedLine === needle.generatedLine
? section.generatedOffset.generatedColumn - 1
: 0),
bias: aArgs.bias
});
};
/**
* Return true if we have the source content for every source in the source
* map, false otherwise.
*/
IndexedSourceMapConsumer.prototype.hasContentsOfAllSources =
function IndexedSourceMapConsumer_hasContentsOfAllSources() {
return this._sections.every(function (s) {
return s.consumer.hasContentsOfAllSources();
});
};
/**
* Returns the original source content. The only argument is the url of the
* original source file. Returns null if no original source content is
* available.
*/
IndexedSourceMapConsumer.prototype.sourceContentFor =
function IndexedSourceMapConsumer_sourceContentFor(aSource, nullOnMissing) {
for (var i = 0; i < this._sections.length; i++) {
var section = this._sections[i];
var content = section.consumer.sourceContentFor(aSource, true);
if (content) {
return content;
}
}
if (nullOnMissing) {
return null;
}
else {
throw new Error('"' + aSource + '" is not in the SourceMap.');
}
};
/**
* Returns the generated line and column information for the original source,
* line, and column positions provided. The only argument is an object with
* the following properties:
*
* - source: The filename of the original source.
* - line: The line number in the original source.
* - column: The column number in the original source.
*
* and an object is returned with the following properties:
*
* - line: The line number in the generated source, or null.
* - column: The column number in the generated source, or null.
*/
IndexedSourceMapConsumer.prototype.generatedPositionFor =
function IndexedSourceMapConsumer_generatedPositionFor(aArgs) {
for (var i = 0; i < this._sections.length; i++) {
var section = this._sections[i];
// Only consider this section if the requested source is in the list of
// sources of the consumer.
if (section.consumer.sources.indexOf(util.getArg(aArgs, 'source')) === -1) {
continue;
}
var generatedPosition = section.consumer.generatedPositionFor(aArgs);
if (generatedPosition) {
var ret = {
line: generatedPosition.line +
(section.generatedOffset.generatedLine - 1),
column: generatedPosition.column +
(section.generatedOffset.generatedLine === generatedPosition.line
? section.generatedOffset.generatedColumn - 1
: 0)
};
return ret;
}
}
return {
line: null,
column: null
};
};
/**
* Parse the mappings in a string in to a data structure which we can easily
* query (the ordered arrays in the `this.__generatedMappings` and
* `this.__originalMappings` properties).
*/
IndexedSourceMapConsumer.prototype._parseMappings =
function IndexedSourceMapConsumer_parseMappings(aStr, aSourceRoot) {
this.__generatedMappings = [];
this.__originalMappings = [];
for (var i = 0; i < this._sections.length; i++) {
var section = this._sections[i];
var sectionMappings = section.consumer._generatedMappings;
for (var j = 0; j < sectionMappings.length; j++) {
var mapping = sectionMappings[j];
var source = section.consumer._sources.at(mapping.source);
if (section.consumer.sourceRoot !== null) {
source = util.join(section.consumer.sourceRoot, source);
}
this._sources.add(source);
source = this._sources.indexOf(source);
var name = section.consumer._names.at(mapping.name);
this._names.add(name);
name = this._names.indexOf(name);
// The mappings coming from the consumer for the section have
// generated positions relative to the start of the section, so we
// need to offset them to be relative to the start of the concatenated
// generated file.
var adjustedMapping = {
source: source,
generatedLine: mapping.generatedLine +
(section.generatedOffset.generatedLine - 1),
generatedColumn: mapping.generatedColumn +
(section.generatedOffset.generatedLine === mapping.generatedLine
? section.generatedOffset.generatedColumn - 1
: 0),
originalLine: mapping.originalLine,
originalColumn: mapping.originalColumn,
name: name
};
this.__generatedMappings.push(adjustedMapping);
if (typeof adjustedMapping.originalLine === 'number') {
this.__originalMappings.push(adjustedMapping);
}
}
}
quickSort(this.__generatedMappings, util.compareByGeneratedPositionsDeflated);
quickSort(this.__originalMappings, util.compareByOriginalPositions);
};
exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var base64VLQ = require('./base64-vlq');
var util = require('./util');
var ArraySet = require('./array-set').ArraySet;
var MappingList = require('./mapping-list').MappingList;
/**
* An instance of the SourceMapGenerator represents a source map which is
* being built incrementally. You may pass an object with the following
* properties:
*
* - file: The filename of the generated source.
* - sourceRoot: A root for all relative URLs in this source map.
*/
function SourceMapGenerator(aArgs) {
if (!aArgs) {
aArgs = {};
}
this._file = util.getArg(aArgs, 'file', null);
this._sourceRoot = util.getArg(aArgs, 'sourceRoot', null);
this._skipValidation = util.getArg(aArgs, 'skipValidation', false);
this._sources = new ArraySet();
this._names = new ArraySet();
this._mappings = new MappingList();
this._sourcesContents = null;
}
SourceMapGenerator.prototype._version = 3;
/**
* Creates a new SourceMapGenerator based on a SourceMapConsumer
*
* @param aSourceMapConsumer The SourceMap.
*/
SourceMapGenerator.fromSourceMap =
function SourceMapGenerator_fromSourceMap(aSourceMapConsumer) {
var sourceRoot = aSourceMapConsumer.sourceRoot;
var generator = new SourceMapGenerator({
file: aSourceMapConsumer.file,
sourceRoot: sourceRoot
});
aSourceMapConsumer.eachMapping(function (mapping) {
var newMapping = {
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn
}
};
if (mapping.source != null) {
newMapping.source = mapping.source;
if (sourceRoot != null) {
newMapping.source = util.relative(sourceRoot, newMapping.source);
}
newMapping.original = {
line: mapping.originalLine,
column: mapping.originalColumn
};
if (mapping.name != null) {
newMapping.name = mapping.name;
}
}
generator.addMapping(newMapping);
});
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
generator.setSourceContent(sourceFile, content);
}
});
return generator;
};
/**
* Add a single mapping from original source line and column to the generated
* source's line and column for this source map being created. The mapping
* object should have the following properties:
*
* - generated: An object with the generated line and column positions.
* - original: An object with the original line and column positions.
* - source: The original source file (relative to the sourceRoot).
* - name: An optional original token name for this mapping.
*/
SourceMapGenerator.prototype.addMapping =
function SourceMapGenerator_addMapping(aArgs) {
var generated = util.getArg(aArgs, 'generated');
var original = util.getArg(aArgs, 'original', null);
var source = util.getArg(aArgs, 'source', null);
var name = util.getArg(aArgs, 'name', null);
if (!this._skipValidation) {
this._validateMapping(generated, original, source, name);
}
if (source != null) {
source = String(source);
if (!this._sources.has(source)) {
this._sources.add(source);
}
}
if (name != null) {
name = String(name);
if (!this._names.has(name)) {
this._names.add(name);
}
}
this._mappings.add({
generatedLine: generated.line,
generatedColumn: generated.column,
originalLine: original != null && original.line,
originalColumn: original != null && original.column,
source: source,
name: name
});
};
/**
* Set the source content for a source file.
*/
SourceMapGenerator.prototype.setSourceContent =
function SourceMapGenerator_setSourceContent(aSourceFile, aSourceContent) {
var source = aSourceFile;
if (this._sourceRoot != null) {
source = util.relative(this._sourceRoot, source);
}
if (aSourceContent != null) {
// Add the source content to the _sourcesContents map.
// Create a new _sourcesContents map if the property is null.
if (!this._sourcesContents) {
this._sourcesContents = Object.create(null);
}
this._sourcesContents[util.toSetString(source)] = aSourceContent;
} else if (this._sourcesContents) {
// Remove the source file from the _sourcesContents map.
// If the _sourcesContents map is empty, set the property to null.
delete this._sourcesContents[util.toSetString(source)];
if (Object.keys(this._sourcesContents).length === 0) {
this._sourcesContents = null;
}
}
};
/**
* Applies the mappings of a sub-source-map for a specific source file to the
* source map being generated. Each mapping to the supplied source file is
* rewritten using the supplied source map. Note: The resolution for the
* resulting mappings is the minimium of this map and the supplied map.
*
* @param aSourceMapConsumer The source map to be applied.
* @param aSourceFile Optional. The filename of the source file.
* If omitted, SourceMapConsumer's file property will be used.
* @param aSourceMapPath Optional. The dirname of the path to the source map
* to be applied. If relative, it is relative to the SourceMapConsumer.
* This parameter is needed when the two source maps aren't in the same
* directory, and the source map to be applied contains relative source
* paths. If so, those relative source paths need to be rewritten
* relative to the SourceMapGenerator.
*/
SourceMapGenerator.prototype.applySourceMap =
function SourceMapGenerator_applySourceMap(aSourceMapConsumer, aSourceFile, aSourceMapPath) {
var sourceFile = aSourceFile;
// If aSourceFile is omitted, we will use the file property of the SourceMap
if (aSourceFile == null) {
if (aSourceMapConsumer.file == null) {
throw new Error(
'SourceMapGenerator.prototype.applySourceMap requires either an explicit source file, ' +
'or the source map\'s "file" property. Both were omitted.'
);
}
sourceFile = aSourceMapConsumer.file;
}
var sourceRoot = this._sourceRoot;
// Make "sourceFile" relative if an absolute Url is passed.
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
// Applying the SourceMap can add and remove items from the sources and
// the names array.
var newSources = new ArraySet();
var newNames = new ArraySet();
// Find mappings for the "sourceFile"
this._mappings.unsortedForEach(function (mapping) {
if (mapping.source === sourceFile && mapping.originalLine != null) {
// Check if it can be mapped by the source map, then update the mapping.
var original = aSourceMapConsumer.originalPositionFor({
line: mapping.originalLine,
column: mapping.originalColumn
});
if (original.source != null) {
// Copy mapping
mapping.source = original.source;
if (aSourceMapPath != null) {
mapping.source = util.join(aSourceMapPath, mapping.source)
}
if (sourceRoot != null) {
mapping.source = util.relative(sourceRoot, mapping.source);
}
mapping.originalLine = original.line;
mapping.originalColumn = original.column;
if (original.name != null) {
mapping.name = original.name;
}
}
}
var source = mapping.source;
if (source != null && !newSources.has(source)) {
newSources.add(source);
}
var name = mapping.name;
if (name != null && !newNames.has(name)) {
newNames.add(name);
}
}, this);
this._sources = newSources;
this._names = newNames;
// Copy sourcesContents of applied map.
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
if (aSourceMapPath != null) {
sourceFile = util.join(aSourceMapPath, sourceFile);
}
if (sourceRoot != null) {
sourceFile = util.relative(sourceRoot, sourceFile);
}
this.setSourceContent(sourceFile, content);
}
}, this);
};
/**
* A mapping can have one of the three levels of data:
*
* 1. Just the generated position.
* 2. The Generated position, original position, and original source.
* 3. Generated and original position, original source, as well as a name
* token.
*
* To maintain consistency, we validate that any new mapping being added falls
* in to one of these categories.
*/
SourceMapGenerator.prototype._validateMapping =
function SourceMapGenerator_validateMapping(aGenerated, aOriginal, aSource,
aName) {
if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aGenerated.line > 0 && aGenerated.column >= 0
&& !aOriginal && !aSource && !aName) {
// Case 1.
return;
}
else if (aGenerated && 'line' in aGenerated && 'column' in aGenerated
&& aOriginal && 'line' in aOriginal && 'column' in aOriginal
&& aGenerated.line > 0 && aGenerated.column >= 0
&& aOriginal.line > 0 && aOriginal.column >= 0
&& aSource) {
// Cases 2 and 3.
return;
}
else {
throw new Error('Invalid mapping: ' + JSON.stringify({
generated: aGenerated,
source: aSource,
original: aOriginal,
name: aName
}));
}
};
/**
* Serialize the accumulated mappings in to the stream of base 64 VLQs
* specified by the source map format.
*/
SourceMapGenerator.prototype._serializeMappings =
function SourceMapGenerator_serializeMappings() {
var previousGeneratedColumn = 0;
var previousGeneratedLine = 1;
var previousOriginalColumn = 0;
var previousOriginalLine = 0;
var previousName = 0;
var previousSource = 0;
var result = '';
var next;
var mapping;
var nameIdx;
var sourceIdx;
var mappings = this._mappings.toArray();
for (var i = 0, len = mappings.length; i < len; i++) {
mapping = mappings[i];
next = ''
if (mapping.generatedLine !== previousGeneratedLine) {
previousGeneratedColumn = 0;
while (mapping.generatedLine !== previousGeneratedLine) {
next += ';';
previousGeneratedLine++;
}
}
else {
if (i > 0) {
if (!util.compareByGeneratedPositionsInflated(mapping, mappings[i - 1])) {
continue;
}
next += ',';
}
}
next += base64VLQ.encode(mapping.generatedColumn
- previousGeneratedColumn);
previousGeneratedColumn = mapping.generatedColumn;
if (mapping.source != null) {
sourceIdx = this._sources.indexOf(mapping.source);
next += base64VLQ.encode(sourceIdx - previousSource);
previousSource = sourceIdx;
// lines are stored 0-based in SourceMap spec version 3
next += base64VLQ.encode(mapping.originalLine - 1
- previousOriginalLine);
previousOriginalLine = mapping.originalLine - 1;
next += base64VLQ.encode(mapping.originalColumn
- previousOriginalColumn);
previousOriginalColumn = mapping.originalColumn;
if (mapping.name != null) {
nameIdx = this._names.indexOf(mapping.name);
next += base64VLQ.encode(nameIdx - previousName);
previousName = nameIdx;
}
}
result += next;
}
return result;
};
SourceMapGenerator.prototype._generateSourcesContent =
function SourceMapGenerator_generateSourcesContent(aSources, aSourceRoot) {
return aSources.map(function (source) {
if (!this._sourcesContents) {
return null;
}
if (aSourceRoot != null) {
source = util.relative(aSourceRoot, source);
}
var key = util.toSetString(source);
return Object.prototype.hasOwnProperty.call(this._sourcesContents, key)
? this._sourcesContents[key]
: null;
}, this);
};
/**
* Externalize the source map.
*/
SourceMapGenerator.prototype.toJSON =
function SourceMapGenerator_toJSON() {
var map = {
version: this._version,
sources: this._sources.toArray(),
names: this._names.toArray(),
mappings: this._serializeMappings()
};
if (this._file != null) {
map.file = this._file;
}
if (this._sourceRoot != null) {
map.sourceRoot = this._sourceRoot;
}
if (this._sourcesContents) {
map.sourcesContent = this._generateSourcesContent(map.sources, map.sourceRoot);
}
return map;
};
/**
* Render the source map being generated to a string.
*/
SourceMapGenerator.prototype.toString =
function SourceMapGenerator_toString() {
return JSON.stringify(this.toJSON());
};
exports.SourceMapGenerator = SourceMapGenerator;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */
/*
* Copyright 2011 Mozilla Foundation and contributors
* Licensed under the New BSD license. See LICENSE or:
* http://opensource.org/licenses/BSD-3-Clause
*/
var SourceMapGenerator = require('./source-map-generator').SourceMapGenerator;
var util = require('./util');
// Matches a Windows-style `\r\n` newline or a `\n` newline used by all other
// operating systems these days (capturing the result).
var REGEX_NEWLINE = /(\r?\n)/;
// Newline character code for charCodeAt() comparisons
var NEWLINE_CODE = 10;
// Private symbol for identifying `SourceNode`s when multiple versions of
// the source-map library are loaded. This MUST NOT CHANGE across
// versions!
var isSourceNode = "$$$isSourceNode$$$";
/**
* SourceNodes provide a way to abstract over interpolating/concatenating
* snippets of generated JavaScript source code while maintaining the line and
* column information associated with the original source code.
*
* @param aLine The original line number.
* @param aColumn The original column number.
* @param aSource The original source's filename.
* @param aChunks Optional. An array of strings which are snippets of
* generated JS, or other SourceNodes.
* @param aName The original identifier.
*/
function SourceNode(aLine, aColumn, aSource, aChunks, aName) {
this.children = [];
this.sourceContents = {};
this.line = aLine == null ? null : aLine;
this.column = aColumn == null ? null : aColumn;
this.source = aSource == null ? null : aSource;
this.name = aName == null ? null : aName;
this[isSourceNode] = true;
if (aChunks != null) this.add(aChunks);
}
/**
* Creates a SourceNode from generated code and a SourceMapConsumer.
*
* @param aGeneratedCode The generated code
* @param aSourceMapConsumer The SourceMap for the generated code
* @param aRelativePath Optional. The path that relative sources in the
* SourceMapConsumer should be relative to.
*/
SourceNode.fromStringWithSourceMap =
function SourceNode_fromStringWithSourceMap(aGeneratedCode, aSourceMapConsumer, aRelativePath) {
// The SourceNode we want to fill with the generated code
// and the SourceMap
var node = new SourceNode();
// All even indices of this array are one line of the generated code,
// while all odd indices are the newlines between two adjacent lines
// (since `REGEX_NEWLINE` captures its match).
// Processed fragments are removed from this array, by calling `shiftNextLine`.
var remainingLines = aGeneratedCode.split(REGEX_NEWLINE);
var shiftNextLine = function() {
var lineContents = remainingLines.shift();
// The last line of a file might not have a newline.
var newLine = remainingLines.shift() || "";
return lineContents + newLine;
};
// We need to remember the position of "remainingLines"
var lastGeneratedLine = 1, lastGeneratedColumn = 0;
// The generate SourceNodes we need a code range.
// To extract it current and last mapping is used.
// Here we store the last mapping.
var lastMapping = null;
aSourceMapConsumer.eachMapping(function (mapping) {
if (lastMapping !== null) {
// We add the code from "lastMapping" to "mapping":
// First check if there is a new line in between.
if (lastGeneratedLine < mapping.generatedLine) {
// Associate first line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
lastGeneratedLine++;
lastGeneratedColumn = 0;
// The remaining code is added without mapping
} else {
// There is no new line in between.
// Associate the code between "lastGeneratedColumn" and
// "mapping.generatedColumn" with "lastMapping"
var nextLine = remainingLines[0];
var code = nextLine.substr(0, mapping.generatedColumn -
lastGeneratedColumn);
remainingLines[0] = nextLine.substr(mapping.generatedColumn -
lastGeneratedColumn);
lastGeneratedColumn = mapping.generatedColumn;
addMappingWithCode(lastMapping, code);
// No more remaining code, continue
lastMapping = mapping;
return;
}
}
// We add the generated code until the first mapping
// to the SourceNode without any mapping.
// Each line is added as separate string.
while (lastGeneratedLine < mapping.generatedLine) {
node.add(shiftNextLine());
lastGeneratedLine++;
}
if (lastGeneratedColumn < mapping.generatedColumn) {
var nextLine = remainingLines[0];
node.add(nextLine.substr(0, mapping.generatedColumn));
remainingLines[0] = nextLine.substr(mapping.generatedColumn);
lastGeneratedColumn = mapping.generatedColumn;
}
lastMapping = mapping;
}, this);
// We have processed all mappings.
if (remainingLines.length > 0) {
if (lastMapping) {
// Associate the remaining code in the current line with "lastMapping"
addMappingWithCode(lastMapping, shiftNextLine());
}
// and add the remaining lines without any mapping
node.add(remainingLines.join(""));
}
// Copy sourcesContent into SourceNode
aSourceMapConsumer.sources.forEach(function (sourceFile) {
var content = aSourceMapConsumer.sourceContentFor(sourceFile);
if (content != null) {
if (aRelativePath != null) {
sourceFile = util.join(aRelativePath, sourceFile);
}
node.setSourceContent(sourceFile, content);
}
});
return node;
function addMappingWithCode(mapping, code) {
if (mapping === null || mapping.source === undefined) {
node.add(code);
} else {
var source = aRelativePath
? util.join(aRelativePath, mapping.source)
: mapping.source;
node.add(new SourceNode(mapping.originalLine,
mapping.originalColumn,
source,
code,
mapping.name));
}
}
};
/**
* Add a chunk of generated JS to this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.add = function SourceNode_add(aChunk) {
if (Array.isArray(aChunk)) {
aChunk.forEach(function (chunk) {
this.add(chunk);
}, this);
}
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
if (aChunk) {
this.children.push(aChunk);
}
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Add a chunk of generated JS to the beginning of this source node.
*
* @param aChunk A string snippet of generated JS code, another instance of
* SourceNode, or an array where each member is one of those things.
*/
SourceNode.prototype.prepend = function SourceNode_prepend(aChunk) {
if (Array.isArray(aChunk)) {
for (var i = aChunk.length-1; i >= 0; i--) {
this.prepend(aChunk[i]);
}
}
else if (aChunk[isSourceNode] || typeof aChunk === "string") {
this.children.unshift(aChunk);
}
else {
throw new TypeError(
"Expected a SourceNode, string, or an array of SourceNodes and strings. Got " + aChunk
);
}
return this;
};
/**
* Walk over the tree of JS snippets in this node and its children. The
* walking function is called once for each snippet of JS and is passed that
* snippet and the its original associated source's line/column location.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walk = function SourceNode_walk(aFn) {
var chunk;
for (var i = 0, len = this.children.length; i < len; i++) {
chunk = this.children[i];
if (chunk[isSourceNode]) {
chunk.walk(aFn);
}
else {
if (chunk !== '') {
aFn(chunk, { source: this.source,
line: this.line,
column: this.column,
name: this.name });
}
}
}
};
/**
* Like `String.prototype.join` except for SourceNodes. Inserts `aStr` between
* each of `this.children`.
*
* @param aSep The separator.
*/
SourceNode.prototype.join = function SourceNode_join(aSep) {
var newChildren;
var i;
var len = this.children.length;
if (len > 0) {
newChildren = [];
for (i = 0; i < len-1; i++) {
newChildren.push(this.children[i]);
newChildren.push(aSep);
}
newChildren.push(this.children[i]);
this.children = newChildren;
}
return this;
};
/**
* Call String.prototype.replace on the very right-most source snippet. Useful
* for trimming whitespace from the end of a source node, etc.
*
* @param aPattern The pattern to replace.
* @param aReplacement The thing to replace the pattern with.
*/
SourceNode.prototype.replaceRight = function SourceNode_replaceRight(aPattern, aReplacement) {
var lastChild = this.children[this.children.length - 1];
if (lastChild[isSourceNode]) {
lastChild.replaceRight(aPattern, aReplacement);
}
else if (typeof lastChild === 'string') {
this.children[this.children.length - 1] = lastChild.replace(aPattern, aReplacement);
}
else {
this.children.push(''.replace(aPattern, aReplacement));
}
return this;
};
/**
* Set the source content for a source file. This will be added to the SourceMapGenerator
* in the sourcesContent field.
*
* @param aSourceFile The filename of the source file
* @param aSourceContent The content of the source file
*/
SourceNode.prototype.setSourceContent =
function SourceNode_setSourceContent(aSourceFile, aSourceContent) {
this.sourceContents[util.toSetString(aSourceFile)] = aSourceContent;
};
/**
* Walk over the tree of SourceNodes. The walking function is called for each
* source file content and is passed the filename and source content.
*
* @param aFn The traversal function.
*/
SourceNode.prototype.walkSourceContents =
function SourceNode_walkSourceContents(aFn) {
for (var i = 0, len = this.children.length; i < len; i++) {
if (this.children[i][isSourceNode]) {
this.children[i].walkSourceContents(aFn);
}
}
var sources = Object.keys(this.sourceContents);
for (var i = 0, len = sources.length; i < len; i++) {
aFn(util.fromSetString(sources[i]), this.sourceContents[sources[i]]);
}
};
/**
* Return the string representation of this source node. Walks over the tree
* and concatenates all the various snippets together to one string.
*/
SourceNode.prototype.toString = function SourceNode_toString() {
var str = "";
this.walk(function (chunk) {
str += chunk;
});
return str;
};
/**
* Returns the string representation of this source node along with a source
* map.
*/
SourceNode.prototype.toStringWithSourceMap = function SourceNode_toStringWithSourceMap(aArgs) {
var generated = {
code: "",
line: 1,
column: 0
};
var map = new SourceMapGenerator(aArgs);
var sourceMappingActive = false;
var lastOriginalSource = null;
var lastOriginalLine = null;
var lastOriginalColumn = null;
var lastOriginalName = null;
this.walk(function (chunk, original) {
generated.code += chunk;
if (original.source !== null
&& original.line !== null
&& original.column !== null) {
if(lastOriginalSource !== original.source
|| lastOriginalLine !== original.line
|| lastOriginalColumn !== original.column
|| lastOriginalName !== original.name) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column
},
generated: {
line: generated.line,
column: generated.column
},
name: original.name
});
}
lastOriginalSource = original.source;
lastOriginalLine = original.line;
lastOriginalColumn = original.column;
lastOriginalName = original.name;
sourceMappingActive = true;
} else if (sourceMappingActive) {
map.addMapping({
generated: {
line: generated.line,
column: generated.column
}
});
lastOriginalSource = null;
sourceMappingActive = false;
}
for (var idx = 0, length = chunk.length; idx < length; idx++) {
if (chunk.charCodeAt(idx) === NEWLINE_CODE) {
generated.line++;
generated.column = 0;
// Mappings end at eol
if (idx + 1 === length) {
lastOriginalSource = null;
sourceMappingActive = false;
} else if (sourceMappingActive) {
map.addMapping({
source: original.source,
original: {
line: original.line,
column: original.column
},
generated: {
line: generated.line,
column: generated.column
},
name: original.name
});
}
} else {
generated.column++;
}
}
});
this.walkSourceContents(function (sourceFile, sourceContent) {
map.setSourceContent(sourceFile, sourceContent);
});
return { code: generated.code, map: map };
};
exports.SourceNode = SourceNode;
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* -*- Mode: js; js-indent-level: 2; -*- */ /* * Copyright 2011 Mozilla Foundation and contributors * Licensed under the New BSD license. See LICENSE or: * http://opensource.org/licenses/BSD-3-Clause */ /** * This is a helper function for getting values from parameter/options * objects. * * @param args The object we are extracting values from * @param name The name of the property we are getting. * @param defaultValue An optional value to return if the property is missing * from the object. If this is not specified and the property is missing, an * error will be thrown. */ function getArg(aArgs, aName, aDefaultValue) { if (aName in aArgs) { return aArgs[aName]; } else if (arguments.length === 3) { return aDefaultValue; } else { throw new Error('"' + aName + '" is a required argument.'); } } exports.getArg = getArg; var urlRegexp = /^(?:([\w+\-.]+):)?\/\/(?:(\w+:\w+)@)?([\w.]*)(?::(\d+))?(\S*)$/; var dataUrlRegexp = /^data:.+\,.+$/; function urlParse(aUrl) { var match = aUrl.match(urlRegexp); if (!match) { return null; } return { scheme: match[1], auth: match[2], host: match[3], port: match[4], path: match[5] }; } exports.urlParse = urlParse; function urlGenerate(aParsedUrl) { var url = ''; if (aParsedUrl.scheme) { url += aParsedUrl.scheme + ':'; } url += '//'; if (aParsedUrl.auth) { url += aParsedUrl.auth + '@'; } if (aParsedUrl.host) { url += aParsedUrl.host; } if (aParsedUrl.port) { url += ":" + aParsedUrl.port } if (aParsedUrl.path) { url += aParsedUrl.path; } return url; } exports.urlGenerate = urlGenerate; /** * Normalizes a path, or the path portion of a URL: * * - Replaces consecutive slashes with one slash. * - Removes unnecessary '.' parts. * - Removes unnecessary '<dir>/..' parts. * * Based on code in the Node.js 'path' core module. * * @param aPath The path or url to normalize. */ function normalize(aPath) { var path = aPath; var url = urlParse(aPath); if (url) { if (!url.path) { return aPath; } path = url.path; } var isAbsolute = exports.isAbsolute(path); var parts = path.split(/\/+/); for (var part, up = 0, i = parts.length - 1; i >= 0; i--) { part = parts[i]; if (part === '.') { parts.splice(i, 1); } else if (part === '..') { up++; } else if (up > 0) { if (part === '') { // The first part is blank if the path is absolute. Trying to go // above the root is a no-op. Therefore we can remove all '..' parts // directly after the root. parts.splice(i + 1, up); up = 0; } else { parts.splice(i, 2); up--; } } } path = parts.join('/'); if (path === '') { path = isAbsolute ? '/' : '.'; } if (url) { url.path = path; return urlGenerate(url); } return path; } exports.normalize = normalize; /** * Joins two paths/URLs. * * @param aRoot The root path or URL. * @param aPath The path or URL to be joined with the root. * * - If aPath is a URL or a data URI, aPath is returned, unless aPath is a * scheme-relative URL: Then the scheme of aRoot, if any, is prepended * first. * - Otherwise aPath is a path. If aRoot is a URL, then its path portion * is updated with the result and aRoot is returned. Otherwise the result * is returned. * - If aPath is absolute, the result is aPath. * - Otherwise the two paths are joined with a slash. * - Joining for example 'http://' and 'www.example.com' is also supported. */ function join(aRoot, aPath) { if (aRoot === "") { aRoot = "."; } if (aPath === "") { aPath = "."; } var aPathUrl = urlParse(aPath); var aRootUrl = urlParse(aRoot); if (aRootUrl) { aRoot = aRootUrl.path || '/'; } // `join(foo, '//www.example.org')` if (aPathUrl && !aPathUrl.scheme) { if (aRootUrl) { aPathUrl.scheme = aRootUrl.scheme; } return urlGenerate(aPathUrl); } if (aPathUrl || aPath.match(dataUrlRegexp)) { return aPath; } // `join('http://', 'www.example.com')` if (aRootUrl && !aRootUrl.host && !aRootUrl.path) { aRootUrl.host = aPath; return urlGenerate(aRootUrl); } var joined = aPath.charAt(0) === '/' ? aPath : normalize(aRoot.replace(/\/+$/, '') + '/' + aPath); if (aRootUrl) { aRootUrl.path = joined; return urlGenerate(aRootUrl); } return joined; } exports.join = join; exports.isAbsolute = function (aPath) { return aPath.charAt(0) === '/' || !!aPath.match(urlRegexp); }; /** * Make a path relative to a URL or another path. * * @param aRoot The root path or URL. * @param aPath The path or URL to be made relative to aRoot. */ function relative(aRoot, aPath) { if (aRoot === "") { aRoot = "."; } aRoot = aRoot.replace(/\/$/, ''); // It is possible for the path to be above the root. In this case, simply // checking whether the root is a prefix of the path won't work. Instead, we // need to remove components from the root one by one, until either we find // a prefix that fits, or we run out of components to remove. var level = 0; while (aPath.indexOf(aRoot + '/') !== 0) { var index = aRoot.lastIndexOf("/"); if (index < 0) { return aPath; } // If the only part of the root that is left is the scheme (i.e. http://, // file:///, etc.), one or more slashes (/), or simply nothing at all, we // have exhausted all components, so the path is not relative to the root. aRoot = aRoot.slice(0, index); if (aRoot.match(/^([^\/]+:\/)?\/*$/)) { return aPath; } ++level; } // Make sure we add a "../" for each component we removed from the root. return Array(level + 1).join("../") + aPath.substr(aRoot.length + 1); } exports.relative = relative; var supportsNullProto = (function () { var obj = Object.create(null); return !('__proto__' in obj); }()); function identity (s) { return s; } /** * Because behavior goes wacky when you set `__proto__` on objects, we * have to prefix all the strings in our set with an arbitrary character. * * See https://github.com/mozilla/source-map/pull/31 and * https://github.com/mozilla/source-map/issues/30 * * @param String aStr */ function toSetString(aStr) { if (isProtoString(aStr)) { return '$' + aStr; } return aStr; } exports.toSetString = supportsNullProto ? identity : toSetString; function fromSetString(aStr) { if (isProtoString(aStr)) { return aStr.slice(1); } return aStr; } exports.fromSetString = supportsNullProto ? identity : fromSetString; function isProtoString(s) { if (!s) { return false; } var length = s.length; if (length < 9 /* "__proto__".length */) { return false; } if (s.charCodeAt(length - 1) !== 95 /* '_' */ || s.charCodeAt(length - 2) !== 95 /* '_' */ || s.charCodeAt(length - 3) !== 111 /* 'o' */ || s.charCodeAt(length - 4) !== 116 /* 't' */ || s.charCodeAt(length - 5) !== 111 /* 'o' */ || s.charCodeAt(length - 6) !== 114 /* 'r' */ || s.charCodeAt(length - 7) !== 112 /* 'p' */ || s.charCodeAt(length - 8) !== 95 /* '_' */ || s.charCodeAt(length - 9) !== 95 /* '_' */) { return false; } for (var i = length - 10; i >= 0; i--) { if (s.charCodeAt(i) !== 36 /* '$' */) { return false; } } return true; } /** * Comparator between two mappings where the original positions are compared. * * Optionally pass in `true` as `onlyCompareGenerated` to consider two * mappings with the same original source/line/column, but different generated * line and column the same. Useful when searching for a mapping with a * stubbed out mapping. */ function compareByOriginalPositions(mappingA, mappingB, onlyCompareOriginal) { var cmp = mappingA.source - mappingB.source; if (cmp !== 0) { return cmp; } cmp = mappingA.originalLine - mappingB.originalLine; if (cmp !== 0) { return cmp; } cmp = mappingA.originalColumn - mappingB.originalColumn; if (cmp !== 0 || onlyCompareOriginal) { return cmp; } cmp = mappingA.generatedColumn - mappingB.generatedColumn; if (cmp !== 0) { return cmp; } cmp = mappingA.generatedLine - mappingB.generatedLine; if (cmp !== 0) { return cmp; } return mappingA.name - mappingB.name; } exports.compareByOriginalPositions = compareByOriginalPositions; /** * Comparator between two mappings with deflated source and name indices where * the generated positions are compared. * * Optionally pass in `true` as `onlyCompareGenerated` to consider two * mappings with the same generated line and column, but different * source/name/original line and column the same. Useful when searching for a * mapping with a stubbed out mapping. */ function compareByGeneratedPositionsDeflated(mappingA, mappingB, onlyCompareGenerated) { var cmp = mappingA.generatedLine - mappingB.generatedLine; if (cmp !== 0) { return cmp; } cmp = mappingA.generatedColumn - mappingB.generatedColumn; if (cmp !== 0 || onlyCompareGenerated) { return cmp; } cmp = mappingA.source - mappingB.source; if (cmp !== 0) { return cmp; } cmp = mappingA.originalLine - mappingB.originalLine; if (cmp !== 0) { return cmp; } cmp = mappingA.originalColumn - mappingB.originalColumn; if (cmp !== 0) { return cmp; } return mappingA.name - mappingB.name; } exports.compareByGeneratedPositionsDeflated = compareByGeneratedPositionsDeflated; function strcmp(aStr1, aStr2) { if (aStr1 === aStr2) { return 0; } if (aStr1 > aStr2) { return 1; } return -1; } /** * Comparator between two mappings with inflated source and name strings where * the generated positions are compared. */ function compareByGeneratedPositionsInflated(mappingA, mappingB) { var cmp = mappingA.generatedLine - mappingB.generatedLine; if (cmp !== 0) { return cmp; } cmp = mappingA.generatedColumn - mappingB.generatedColumn; if (cmp !== 0) { return cmp; } cmp = strcmp(mappingA.source, mappingB.source); if (cmp !== 0) { return cmp; } cmp = mappingA.originalLine - mappingB.originalLine; if (cmp !== 0) { return cmp; } cmp = mappingA.originalColumn - mappingB.originalColumn; if (cmp !== 0) { return cmp; } return strcmp(mappingA.name, mappingB.name); } exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflated; |
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 17.57% | (13 / 74) | 0% | (0 / 22) | 0% | (0 / 27) | 17.57% | (13 / 74) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 | 1 1 1 1 1 1 1 1 1 1 1 1 1 | var licenseIDs = require('spdx-license-ids');
function valid(string) {
return licenseIDs.indexOf(string) > -1;
}
// Common transpositions of license identifier acronyms
var transpositions = [
['APGL', 'AGPL'],
['Gpl', 'GPL'],
['GLP', 'GPL'],
['APL', 'Apache'],
['ISD', 'ISC'],
['GLP', 'GPL'],
['IST', 'ISC'],
['Claude', 'Clause'],
[' or later', '+'],
[' International', ''],
['GNU', 'GPL'],
['GUN', 'GPL'],
['+', ''],
['GNU GPL', 'GPL'],
['GNU/GPL', 'GPL'],
['GNU GLP', 'GPL'],
['GNU General Public License', 'GPL'],
['Gnu public license', 'GPL'],
['GNU Public License', 'GPL'],
['GNU GENERAL PUBLIC LICENSE', 'GPL'],
['MTI', 'MIT'],
['Mozilla Public License', 'MPL'],
['WTH', 'WTF'],
['-License', '']
];
var TRANSPOSED = 0;
var CORRECT = 1;
// Simple corrections to nearly valid identifiers.
var transforms = [
// e.g. 'mit'
function(argument) {
return argument.toUpperCase();
},
// e.g. 'MIT '
function(argument) {
return argument.trim();
},
// e.g. 'M.I.T.'
function(argument) {
return argument.replace(/\./g, '');
},
// e.g. 'Apache- 2.0'
function(argument) {
return argument.replace(/\s+/g, '');
},
// e.g. 'CC BY 4.0''
function(argument) {
return argument.replace(/\s+/g, '-');
},
// e.g. 'LGPLv2.1'
function(argument) {
return argument.replace('v', '-');
},
// e.g. 'Apache 2.0'
function(argument) {
return argument.replace(/,?\s*(\d)/, '-$1');
},
// e.g. 'GPL 2'
function(argument) {
return argument.replace(/,?\s*(\d)/, '-$1.0');
},
// e.g. 'Apache Version 2.0'
function(argument) {
return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2');
},
// e.g. 'Apache Version 2'
function(argument) {
return argument.replace(/,?\s*(V\.|v\.|V|v|Version|version)\s*(\d)/, '-$2.0');
},
// e.g. 'ZLIB'
function(argument) {
return argument[0].toUpperCase() + argument.slice(1);
},
// e.g. 'MPL/2.0'
function(argument) {
return argument.replace('/', '-');
},
// e.g. 'Apache 2'
function(argument) {
return argument
.replace(/\s*V\s*(\d)/, '-$1')
.replace(/(\d)$/, '$1.0');
},
// e.g. 'GPL-2.0-'
function(argument) {
return argument.slice(0, argument.length - 1);
},
// e.g. 'GPL2'
function(argument) {
return argument.replace(/(\d)$/, '-$1.0');
},
// e.g. 'BSD 3'
function(argument) {
return argument.replace(/(-| )?(\d)$/, '-$2-Clause');
},
// e.g. 'BSD clause 3'
function(argument) {
return argument.replace(/(-| )clause(-| )(\d)/, '-$3-Clause');
},
// e.g. 'BY-NC-4.0'
function(argument) {
return 'CC-' + argument;
},
// e.g. 'BY-NC'
function(argument) {
return 'CC-' + argument + '-4.0';
},
// e.g. 'Attribution-NonCommercial'
function(argument) {
return argument
.replace('Attribution', 'BY')
.replace('NonCommercial', 'NC')
.replace('NoDerivatives', 'ND')
.replace(/ (\d)/, '-$1')
.replace(/ ?International/, '');
},
// e.g. 'Attribution-NonCommercial'
function(argument) {
return 'CC-' +
argument
.replace('Attribution', 'BY')
.replace('NonCommercial', 'NC')
.replace('NoDerivatives', 'ND')
.replace(/ (\d)/, '-$1')
.replace(/ ?International/, '') +
'-4.0';
}
];
// If all else fails, guess that strings containing certain substrings
// meant to identify certain licenses.
var lastResorts = [
['UNLI', 'Unlicense'],
['WTF', 'WTFPL'],
['2 CLAUSE', 'BSD-2-Clause'],
['2-CLAUSE', 'BSD-2-Clause'],
['3 CLAUSE', 'BSD-3-Clause'],
['3-CLAUSE', 'BSD-3-Clause'],
['AFFERO', 'AGPL-3.0'],
['AGPL', 'AGPL-3.0'],
['APACHE', 'Apache-2.0'],
['ARTISTIC', 'Artistic-2.0'],
['Affero', 'AGPL-3.0'],
['BEER', 'Beerware'],
['BOOST', 'BSL-1.0'],
['BSD', 'BSD-2-Clause'],
['ECLIPSE', 'EPL-1.0'],
['FUCK', 'WTFPL'],
['GNU', 'GPL-3.0'],
['LGPL', 'LGPL-3.0'],
['GPL', 'GPL-3.0'],
['MIT', 'MIT'],
['MPL', 'MPL-2.0'],
['X11', 'X11'],
['ZLIB', 'Zlib']
];
var SUBSTRING = 0;
var IDENTIFIER = 1;
var validTransformation = function(identifier) {
for (var i = 0; i < transforms.length; i++) {
var transformed = transforms[i](identifier);
if (transformed !== identifier && valid(transformed)) {
return transformed;
}
}
return null;
};
var validLastResort = function(identifier) {
var upperCased = identifier.toUpperCase();
for (var i = 0; i < lastResorts.length; i++) {
var lastResort = lastResorts[i];
if (upperCased.indexOf(lastResort[SUBSTRING]) > -1) {
return lastResort[IDENTIFIER];
}
}
return null;
};
var anyCorrection = function(identifier, check) {
for (var i = 0; i < transpositions.length; i++) {
var transposition = transpositions[i];
var transposed = transposition[TRANSPOSED];
if (identifier.indexOf(transposed) > -1) {
var corrected = identifier.replace(
transposed,
transposition[CORRECT]
);
var checked = check(corrected);
if (checked !== null) {
return checked;
}
}
}
return null;
};
module.exports = function(identifier) {
identifier = identifier.replace(/\+$/, '');
if (valid(identifier)) {
return identifier;
}
var transformed = validTransformation(identifier);
if (transformed !== null) {
return transformed;
}
transformed = anyCorrection(identifier, function(argument) {
if (valid(argument)) {
return argument;
}
return validTransformation(argument);
});
if (transformed !== null) {
return transformed;
}
transformed = validLastResort(identifier);
if (transformed !== null) {
return transformed;
}
transformed = anyCorrection(identifier, validLastResort);
if (transformed !== null) {
return transformed;
}
return null;
};
|
| 1 2 3 4 5 6 7 | 1 1 | var parser = require('./parser').parser
module.exports = function (argument) {
return parser.parse(argument)
}
|
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 | 1 9 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | /* parser generated by jison 0.4.17 */
/*
Returns a Parser object of the following structure:
Parser: {
yy: {}
}
Parser.prototype: {
yy: {},
trace: function(),
symbols_: {associative list: name ==> number},
terminals_: {associative list: number ==> name},
productions_: [...],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),
table: [...],
defaultActions: {...},
parseError: function(str, hash),
parse: function(input),
lexer: {
EOF: 1,
parseError: function(str, hash),
setInput: function(input),
input: function(),
unput: function(str),
more: function(),
less: function(n),
pastInput: function(),
upcomingInput: function(),
showPosition: function(),
test_match: function(regex_match_array, rule_index),
next: function(),
lex: function(),
begin: function(condition),
popState: function(),
_currentRules: function(),
topState: function(),
pushState: function(condition),
options: {
ranges: boolean (optional: true ==> token location info will include a .range[] member)
flex: boolean (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)
backtrack_lexer: boolean (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)
},
performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),
rules: [...],
conditions: {associative list: name ==> set},
}
}
token location info (@$, _$, etc.): {
first_line: n,
last_line: n,
first_column: n,
last_column: n,
range: [start_number, end_number] (where the numbers are indexes into the input string, regular zero-based)
}
the parseError function receives a 'hash' object with these members for lexer and parser errors: {
text: (matched text)
token: (the produced terminal token, if any)
line: (yylineno)
}
while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {
loc: (yylloc)
expected: (string describing the set of expected tokens)
recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)
}
*/
var spdxparse = (function(){
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,5],$V1=[1,6],$V2=[1,7],$V3=[1,4],$V4=[1,9],$V5=[1,10],$V6=[5,14,15,17],$V7=[5,12,14,15,17];
var parser = {trace: function trace() { },
yy: {},
symbols_: {"error":2,"start":3,"expression":4,"EOS":5,"simpleExpression":6,"LICENSE":7,"PLUS":8,"LICENSEREF":9,"DOCUMENTREF":10,"COLON":11,"WITH":12,"EXCEPTION":13,"AND":14,"OR":15,"OPEN":16,"CLOSE":17,"$accept":0,"$end":1},
terminals_: {2:"error",5:"EOS",7:"LICENSE",8:"PLUS",9:"LICENSEREF",10:"DOCUMENTREF",11:"COLON",12:"WITH",13:"EXCEPTION",14:"AND",15:"OR",16:"OPEN",17:"CLOSE"},
productions_: [0,[3,2],[6,1],[6,2],[6,1],[6,3],[4,1],[4,3],[4,3],[4,3],[4,3]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */
var $0 = $$.length - 1;
switch (yystate) {
case 1:
return this.$ = $$[$0-1]
break;
case 2: case 4: case 5:
this.$ = {license: yytext}
break;
case 3:
this.$ = {license: $$[$0-1], plus: true}
break;
case 6:
this.$ = $$[$0]
break;
case 7:
this.$ = {exception: $$[$0]}
this.$.license = $$[$0-2].license
if ($$[$0-2].hasOwnProperty('plus')) {
this.$.plus = $$[$0-2].plus
}
break;
case 8:
this.$ = {conjunction: 'and', left: $$[$0-2], right: $$[$0]}
break;
case 9:
this.$ = {conjunction: 'or', left: $$[$0-2], right: $$[$0]}
break;
case 10:
this.$ = $$[$0-1]
break;
}
},
table: [{3:1,4:2,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{1:[3]},{5:[1,8],14:$V4,15:$V5},o($V6,[2,6],{12:[1,11]}),{4:12,6:3,7:$V0,9:$V1,10:$V2,16:$V3},o($V7,[2,2],{8:[1,13]}),o($V7,[2,4]),{11:[1,14]},{1:[2,1]},{4:15,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{4:16,6:3,7:$V0,9:$V1,10:$V2,16:$V3},{13:[1,17]},{14:$V4,15:$V5,17:[1,18]},o($V7,[2,3]),{9:[1,19]},o($V6,[2,8]),o([5,15,17],[2,9],{14:$V4}),o($V6,[2,7]),o($V6,[2,10]),o($V7,[2,5])],
defaultActions: {8:[2,1]},
parseError: function parseError(str, hash) {
if (hash.recoverable) {
this.trace(str);
} else {
function _parseError (msg, hash) {
this.message = msg;
this.hash = hash;
}
_parseError.prototype = Error;
throw new _parseError(str, hash);
}
},
parse: function parse(input) {
var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
var args = lstack.slice.call(arguments, 1);
var lexer = Object.create(this.lexer);
var sharedState = { yy: {} };
for (var k in this.yy) {
if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
sharedState.yy[k] = this.yy[k];
}
}
lexer.setInput(input, sharedState.yy);
sharedState.yy.lexer = lexer;
sharedState.yy.parser = this;
if (typeof lexer.yylloc == 'undefined') {
lexer.yylloc = {};
}
var yyloc = lexer.yylloc;
lstack.push(yyloc);
var ranges = lexer.options && lexer.options.ranges;
if (typeof sharedState.yy.parseError === 'function') {
this.parseError = sharedState.yy.parseError;
} else {
this.parseError = Object.getPrototypeOf(this).parseError;
}
function popStack(n) {
stack.length = stack.length - 2 * n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
_token_stack:
var lex = function () {
var token;
token = lexer.lex() || EOF;
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
};
var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
while (true) {
state = stack[stack.length - 1];
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol === null || typeof symbol == 'undefined') {
symbol = lex();
}
action = table[state] && table[state][symbol];
}
if (typeof action === 'undefined' || !action.length || !action[0]) {
var errStr = '';
expected = [];
for (p in table[state]) {
if (this.terminals_[p] && p > TERROR) {
expected.push('\'' + this.terminals_[p] + '\'');
}
}
if (lexer.showPosition) {
errStr = 'Parse error on line ' + (yylineno + 1) + ':\n' + lexer.showPosition() + '\nExpecting ' + expected.join(', ') + ', got \'' + (this.terminals_[symbol] || symbol) + '\'';
} else {
errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\'' + (this.terminals_[symbol] || symbol) + '\'');
}
this.parseError(errStr, {
text: lexer.match,
token: this.terminals_[symbol] || symbol,
line: lexer.yylineno,
loc: yyloc,
expected: expected
});
}
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);
}
switch (action[0]) {
case 1:
stack.push(symbol);
vstack.push(lexer.yytext);
lstack.push(lexer.yylloc);
stack.push(action[1]);
symbol = null;
if (!preErrorSymbol) {
yyleng = lexer.yyleng;
yytext = lexer.yytext;
yylineno = lexer.yylineno;
yyloc = lexer.yylloc;
if (recovering > 0) {
recovering--;
}
} else {
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2:
len = this.productions_[action[1]][1];
yyval.$ = vstack[vstack.length - len];
yyval._$ = {
first_line: lstack[lstack.length - (len || 1)].first_line,
last_line: lstack[lstack.length - 1].last_line,
first_column: lstack[lstack.length - (len || 1)].first_column,
last_column: lstack[lstack.length - 1].last_column
};
if (ranges) {
yyval._$.range = [
lstack[lstack.length - (len || 1)].range[0],
lstack[lstack.length - 1].range[1]
];
}
r = this.performAction.apply(yyval, [
yytext,
yyleng,
yylineno,
sharedState.yy,
action[1],
vstack,
lstack
].concat(args));
if (typeof r !== 'undefined') {
return r;
}
if (len) {
stack = stack.slice(0, -1 * len * 2);
vstack = vstack.slice(0, -1 * len);
lstack = lstack.slice(0, -1 * len);
}
stack.push(this.productions_[action[1]][0]);
vstack.push(yyval.$);
lstack.push(yyval._$);
newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
stack.push(newState);
break;
case 3:
return true;
}
}
return true;
}};
/* generated by jison-lex 0.3.4 */
var lexer = (function(){
var lexer = ({
EOF:1,
parseError:function parseError(str, hash) {
if (this.yy.parser) {
this.yy.parser.parseError(str, hash);
} else {
throw new Error(str);
}
},
// resets the lexer, sets new input
setInput:function (input, yy) {
this.yy = yy || this.yy || {};
this._input = input;
this._more = this._backtrack = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {
first_line: 1,
first_column: 0,
last_line: 1,
last_column: 0
};
if (this.options.ranges) {
this.yylloc.range = [0,0];
}
this.offset = 0;
return this;
},
// consumes and returns one char from the input
input:function () {
var ch = this._input[0];
this.yytext += ch;
this.yyleng++;
this.offset++;
this.match += ch;
this.matched += ch;
var lines = ch.match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno++;
this.yylloc.last_line++;
} else {
this.yylloc.last_column++;
}
if (this.options.ranges) {
this.yylloc.range[1]++;
}
this._input = this._input.slice(1);
return ch;
},
// unshifts one char (or a string) into the input
unput:function (ch) {
var len = ch.length;
var lines = ch.split(/(?:\r\n?|\n)/g);
this._input = ch + this._input;
this.yytext = this.yytext.substr(0, this.yytext.length - len);
//this.yyleng -= len;
this.offset -= len;
var oldLines = this.match.split(/(?:\r\n?|\n)/g);
this.match = this.match.substr(0, this.match.length - 1);
this.matched = this.matched.substr(0, this.matched.length - 1);
if (lines.length - 1) {
this.yylineno -= lines.length - 1;
}
var r = this.yylloc.range;
this.yylloc = {
first_line: this.yylloc.first_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.first_column,
last_column: lines ?
(lines.length === oldLines.length ? this.yylloc.first_column : 0)
+ oldLines[oldLines.length - lines.length].length - lines[0].length :
this.yylloc.first_column - len
};
if (this.options.ranges) {
this.yylloc.range = [r[0], r[0] + this.yyleng - len];
}
this.yyleng = this.yytext.length;
return this;
},
// When called from action, caches matched text and appends it on next action
more:function () {
this._more = true;
return this;
},
// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
reject:function () {
if (this.options.backtrack_lexer) {
this._backtrack = true;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
return this;
},
// retain first n characters of the match
less:function (n) {
this.unput(this.match.slice(n));
},
// displays already matched input, i.e. for error messages
pastInput:function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
},
// displays upcoming input, i.e. for error messages
upcomingInput:function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20-next.length);
}
return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\n/g, "");
},
// displays the character position where the lexing error occurred, i.e. for error messages
showPosition:function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c + "^";
},
// test the lexed token: return FALSE when not a match, otherwise return token
test_match:function (match, indexed_rule) {
var token,
lines,
backup;
if (this.options.backtrack_lexer) {
// save context
backup = {
yylineno: this.yylineno,
yylloc: {
first_line: this.yylloc.first_line,
last_line: this.last_line,
first_column: this.yylloc.first_column,
last_column: this.yylloc.last_column
},
yytext: this.yytext,
match: this.match,
matches: this.matches,
matched: this.matched,
yyleng: this.yyleng,
offset: this.offset,
_more: this._more,
_input: this._input,
yy: this.yy,
conditionStack: this.conditionStack.slice(0),
done: this.done
};
if (this.options.ranges) {
backup.yylloc.range = this.yylloc.range.slice(0);
}
}
lines = match[0].match(/(?:\r\n?|\n).*/g);
if (lines) {
this.yylineno += lines.length;
}
this.yylloc = {
first_line: this.yylloc.last_line,
last_line: this.yylineno + 1,
first_column: this.yylloc.last_column,
last_column: lines ?
lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length :
this.yylloc.last_column + match[0].length
};
this.yytext += match[0];
this.match += match[0];
this.matches = match;
this.yyleng = this.yytext.length;
if (this.options.ranges) {
this.yylloc.range = [this.offset, this.offset += this.yyleng];
}
this._more = false;
this._backtrack = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
if (this.done && this._input) {
this.done = false;
}
if (token) {
return token;
} else if (this._backtrack) {
// recover context
for (var k in backup) {
this[k] = backup[k];
}
return false; // rule action called reject() implying the next rule should be tested instead.
}
return false;
},
// return next match in input
next:function () {
if (this.done) {
return this.EOF;
}
if (!this._input) {
this.done = true;
}
var token,
match,
tempMatch,
index;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i = 0; i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (this.options.backtrack_lexer) {
token = this.test_match(tempMatch, rules[i]);
if (token !== false) {
return token;
} else if (this._backtrack) {
match = false;
continue; // rule action called reject() implying a rule MISmatch.
} else {
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
} else if (!this.options.flex) {
break;
}
}
}
if (match) {
token = this.test_match(match, rules[index]);
if (token !== false) {
return token;
}
// else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)
return false;
}
if (this._input === "") {
return this.EOF;
} else {
return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), {
text: "",
token: null,
line: this.yylineno
});
}
},
// return next match that has a token
lex:function lex() {
var r = this.next();
if (r) {
return r;
} else {
return this.lex();
}
},
// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
begin:function begin(condition) {
this.conditionStack.push(condition);
},
// pop the previously active lexer condition state off the condition stack
popState:function popState() {
var n = this.conditionStack.length - 1;
if (n > 0) {
return this.conditionStack.pop();
} else {
return this.conditionStack[0];
}
},
// produce the lexer rule set which is active for the currently active lexer condition state
_currentRules:function _currentRules() {
if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
} else {
return this.conditions["INITIAL"].rules;
}
},
// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
topState:function topState(n) {
n = this.conditionStack.length - 1 - Math.abs(n || 0);
if (n >= 0) {
return this.conditionStack[n];
} else {
return "INITIAL";
}
},
// alias for begin(condition)
pushState:function pushState(condition) {
this.begin(condition);
},
// return the number of states currently on the stack
stateStackSize:function stateStackSize() {
return this.conditionStack.length;
},
options: {},
performAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
var YYSTATE=YY_START;
switch($avoiding_name_collisions) {
case 0:return 5
break;
case 1:/* skip whitespace */
break;
case 2:return 8
break;
case 3:return 16
break;
case 4:return 17
break;
case 5:return 11
break;
case 6:return 10
break;
case 7:return 9
break;
case 8:return 14
break;
case 9:return 15
break;
case 10:return 12
break;
case 11:return 7
break;
case 12:return 7
break;
case 13:return 7
break;
case 14:return 7
break;
case 15:return 7
break;
case 16:return 7
break;
case 17:return 7
break;
case 18:return 7
break;
case 19:return 7
break;
case 20:return 7
break;
case 21:return 7
break;
case 22:return 7
break;
case 23:return 7
break;
case 24:return 13
break;
case 25:return 13
break;
case 26:return 13
break;
case 27:return 13
break;
case 28:return 13
break;
case 29:return 13
break;
case 30:return 13
break;
case 31:return 13
break;
case 32:return 7
break;
case 33:return 13
break;
case 34:return 7
break;
case 35:return 13
break;
case 36:return 7
break;
case 37:return 13
break;
case 38:return 13
break;
case 39:return 7
break;
case 40:return 13
break;
case 41:return 13
break;
case 42:return 13
break;
case 43:return 13
break;
case 44:return 13
break;
case 45:return 7
break;
case 46:return 13
break;
case 47:return 7
break;
case 48:return 7
break;
case 49:return 7
break;
case 50:return 7
break;
case 51:return 7
break;
case 52:return 7
break;
case 53:return 7
break;
case 54:return 7
break;
case 55:return 7
break;
case 56:return 7
break;
case 57:return 7
break;
case 58:return 7
break;
case 59:return 7
break;
case 60:return 7
break;
case 61:return 7
break;
case 62:return 7
break;
case 63:return 13
break;
case 64:return 7
break;
case 65:return 7
break;
case 66:return 13
break;
case 67:return 7
break;
case 68:return 7
break;
case 69:return 7
break;
case 70:return 7
break;
case 71:return 7
break;
case 72:return 7
break;
case 73:return 13
break;
case 74:return 7
break;
case 75:return 13
break;
case 76:return 7
break;
case 77:return 7
break;
case 78:return 7
break;
case 79:return 7
break;
case 80:return 7
break;
case 81:return 7
break;
case 82:return 7
break;
case 83:return 7
break;
case 84:return 7
break;
case 85:return 7
break;
case 86:return 7
break;
case 87:return 7
break;
case 88:return 7
break;
case 89:return 7
break;
case 90:return 7
break;
case 91:return 7
break;
case 92:return 7
break;
case 93:return 7
break;
case 94:return 7
break;
case 95:return 7
break;
case 96:return 7
break;
case 97:return 7
break;
case 98:return 7
break;
case 99:return 7
break;
case 100:return 7
break;
case 101:return 7
break;
case 102:return 7
break;
case 103:return 7
break;
case 104:return 7
break;
case 105:return 7
break;
case 106:return 7
break;
case 107:return 7
break;
case 108:return 7
break;
case 109:return 7
break;
case 110:return 7
break;
case 111:return 7
break;
case 112:return 7
break;
case 113:return 7
break;
case 114:return 7
break;
case 115:return 7
break;
case 116:return 7
break;
case 117:return 7
break;
case 118:return 7
break;
case 119:return 7
break;
case 120:return 7
break;
case 121:return 7
break;
case 122:return 7
break;
case 123:return 7
break;
case 124:return 7
break;
case 125:return 7
break;
case 126:return 7
break;
case 127:return 7
break;
case 128:return 7
break;
case 129:return 7
break;
case 130:return 7
break;
case 131:return 7
break;
case 132:return 7
break;
case 133:return 7
break;
case 134:return 7
break;
case 135:return 7
break;
case 136:return 7
break;
case 137:return 7
break;
case 138:return 7
break;
case 139:return 7
break;
case 140:return 7
break;
case 141:return 7
break;
case 142:return 7
break;
case 143:return 7
break;
case 144:return 7
break;
case 145:return 7
break;
case 146:return 7
break;
case 147:return 7
break;
case 148:return 7
break;
case 149:return 7
break;
case 150:return 7
break;
case 151:return 7
break;
case 152:return 7
break;
case 153:return 7
break;
case 154:return 7
break;
case 155:return 7
break;
case 156:return 7
break;
case 157:return 7
break;
case 158:return 7
break;
case 159:return 7
break;
case 160:return 7
break;
case 161:return 7
break;
case 162:return 7
break;
case 163:return 7
break;
case 164:return 7
break;
case 165:return 7
break;
case 166:return 7
break;
case 167:return 7
break;
case 168:return 7
break;
case 169:return 7
break;
case 170:return 7
break;
case 171:return 7
break;
case 172:return 7
break;
case 173:return 7
break;
case 174:return 7
break;
case 175:return 7
break;
case 176:return 7
break;
case 177:return 7
break;
case 178:return 7
break;
case 179:return 7
break;
case 180:return 7
break;
case 181:return 7
break;
case 182:return 7
break;
case 183:return 7
break;
case 184:return 7
break;
case 185:return 7
break;
case 186:return 7
break;
case 187:return 7
break;
case 188:return 7
break;
case 189:return 7
break;
case 190:return 7
break;
case 191:return 7
break;
case 192:return 7
break;
case 193:return 7
break;
case 194:return 7
break;
case 195:return 7
break;
case 196:return 7
break;
case 197:return 7
break;
case 198:return 7
break;
case 199:return 7
break;
case 200:return 7
break;
case 201:return 7
break;
case 202:return 7
break;
case 203:return 7
break;
case 204:return 7
break;
case 205:return 7
break;
case 206:return 7
break;
case 207:return 7
break;
case 208:return 7
break;
case 209:return 7
break;
case 210:return 7
break;
case 211:return 7
break;
case 212:return 7
break;
case 213:return 7
break;
case 214:return 7
break;
case 215:return 7
break;
case 216:return 7
break;
case 217:return 7
break;
case 218:return 7
break;
case 219:return 7
break;
case 220:return 7
break;
case 221:return 7
break;
case 222:return 7
break;
case 223:return 7
break;
case 224:return 7
break;
case 225:return 7
break;
case 226:return 7
break;
case 227:return 7
break;
case 228:return 7
break;
case 229:return 7
break;
case 230:return 7
break;
case 231:return 7
break;
case 232:return 7
break;
case 233:return 7
break;
case 234:return 7
break;
case 235:return 7
break;
case 236:return 7
break;
case 237:return 7
break;
case 238:return 7
break;
case 239:return 7
break;
case 240:return 7
break;
case 241:return 7
break;
case 242:return 7
break;
case 243:return 7
break;
case 244:return 7
break;
case 245:return 7
break;
case 246:return 7
break;
case 247:return 7
break;
case 248:return 7
break;
case 249:return 7
break;
case 250:return 7
break;
case 251:return 7
break;
case 252:return 7
break;
case 253:return 7
break;
case 254:return 7
break;
case 255:return 7
break;
case 256:return 7
break;
case 257:return 7
break;
case 258:return 7
break;
case 259:return 7
break;
case 260:return 7
break;
case 261:return 7
break;
case 262:return 7
break;
case 263:return 7
break;
case 264:return 7
break;
case 265:return 7
break;
case 266:return 7
break;
case 267:return 7
break;
case 268:return 7
break;
case 269:return 7
break;
case 270:return 7
break;
case 271:return 7
break;
case 272:return 7
break;
case 273:return 7
break;
case 274:return 7
break;
case 275:return 7
break;
case 276:return 7
break;
case 277:return 7
break;
case 278:return 7
break;
case 279:return 7
break;
case 280:return 7
break;
case 281:return 7
break;
case 282:return 7
break;
case 283:return 7
break;
case 284:return 7
break;
case 285:return 7
break;
case 286:return 7
break;
case 287:return 7
break;
case 288:return 7
break;
case 289:return 7
break;
case 290:return 7
break;
case 291:return 7
break;
case 292:return 7
break;
case 293:return 7
break;
case 294:return 7
break;
case 295:return 7
break;
case 296:return 7
break;
case 297:return 7
break;
case 298:return 7
break;
case 299:return 7
break;
case 300:return 7
break;
case 301:return 7
break;
case 302:return 7
break;
case 303:return 7
break;
case 304:return 7
break;
case 305:return 7
break;
case 306:return 7
break;
case 307:return 7
break;
case 308:return 7
break;
case 309:return 7
break;
case 310:return 7
break;
case 311:return 7
break;
case 312:return 7
break;
case 313:return 7
break;
case 314:return 7
break;
case 315:return 7
break;
case 316:return 7
break;
case 317:return 7
break;
case 318:return 7
break;
case 319:return 7
break;
case 320:return 7
break;
case 321:return 7
break;
case 322:return 7
break;
case 323:return 7
break;
case 324:return 7
break;
case 325:return 7
break;
case 326:return 7
break;
case 327:return 7
break;
case 328:return 7
break;
case 329:return 7
break;
case 330:return 7
break;
case 331:return 7
break;
case 332:return 7
break;
case 333:return 7
break;
case 334:return 7
break;
case 335:return 7
break;
case 336:return 7
break;
case 337:return 7
break;
case 338:return 7
break;
case 339:return 7
break;
case 340:return 7
break;
case 341:return 7
break;
case 342:return 7
break;
case 343:return 7
break;
case 344:return 7
break;
case 345:return 7
break;
case 346:return 7
break;
case 347:return 7
break;
case 348:return 7
break;
case 349:return 7
break;
case 350:return 7
break;
case 351:return 7
break;
case 352:return 7
break;
case 353:return 7
break;
case 354:return 7
break;
case 355:return 7
break;
case 356:return 7
break;
case 357:return 7
break;
case 358:return 7
break;
case 359:return 7
break;
case 360:return 7
break;
case 361:return 7
break;
case 362:return 7
break;
case 363:return 7
break;
case 364:return 7
break;
}
},
rules: [/^(?:$)/,/^(?:\s+)/,/^(?:\+)/,/^(?:\()/,/^(?:\))/,/^(?::)/,/^(?:DocumentRef-([0-9A-Za-z-+.]+))/,/^(?:LicenseRef-([0-9A-Za-z-+.]+))/,/^(?:AND)/,/^(?:OR)/,/^(?:WITH)/,/^(?:BSD-3-Clause-No-Nuclear-License-2014)/,/^(?:BSD-3-Clause-No-Nuclear-Warranty)/,/^(?:GPL-2\.0-with-classpath-exception)/,/^(?:GPL-3\.0-with-autoconf-exception)/,/^(?:GPL-2\.0-with-autoconf-exception)/,/^(?:BSD-3-Clause-No-Nuclear-License)/,/^(?:MPL-2\.0-no-copyleft-exception)/,/^(?:GPL-2\.0-with-bison-exception)/,/^(?:GPL-2\.0-with-font-exception)/,/^(?:GPL-2\.0-with-GCC-exception)/,/^(?:CNRI-Python-GPL-Compatible)/,/^(?:GPL-3\.0-with-GCC-exception)/,/^(?:BSD-3-Clause-Attribution)/,/^(?:Classpath-exception-2\.0)/,/^(?:WxWindows-exception-3\.1)/,/^(?:freertos-exception-2\.0)/,/^(?:Autoconf-exception-3\.0)/,/^(?:i2p-gpl-java-exception)/,/^(?:gnu-javamail-exception)/,/^(?:Nokia-Qt-exception-1\.1)/,/^(?:Autoconf-exception-2\.0)/,/^(?:BSD-2-Clause-FreeBSD)/,/^(?:u-boot-exception-2\.0)/,/^(?:zlib-acknowledgement)/,/^(?:Bison-exception-2\.2)/,/^(?:BSD-2-Clause-NetBSD)/,/^(?:CLISP-exception-2\.0)/,/^(?:eCos-exception-2\.0)/,/^(?:BSD-3-Clause-Clear)/,/^(?:Font-exception-2\.0)/,/^(?:FLTK-exception-2\.0)/,/^(?:GCC-exception-2\.0)/,/^(?:Qwt-exception-1\.0)/,/^(?:Libtool-exception)/,/^(?:BSD-3-Clause-LBNL)/,/^(?:GCC-exception-3\.1)/,/^(?:Artistic-1\.0-Perl)/,/^(?:Artistic-1\.0-cl8)/,/^(?:CC-BY-NC-SA-2\.5)/,/^(?:MIT-advertising)/,/^(?:BSD-Source-Code)/,/^(?:CC-BY-NC-SA-4\.0)/,/^(?:LiLiQ-Rplus-1\.1)/,/^(?:CC-BY-NC-SA-3\.0)/,/^(?:BSD-4-Clause-UC)/,/^(?:CC-BY-NC-SA-2\.0)/,/^(?:CC-BY-NC-SA-1\.0)/,/^(?:CC-BY-NC-ND-4\.0)/,/^(?:CC-BY-NC-ND-3\.0)/,/^(?:CC-BY-NC-ND-2\.5)/,/^(?:CC-BY-NC-ND-2\.0)/,/^(?:CC-BY-NC-ND-1\.0)/,/^(?:LZMA-exception)/,/^(?:BitTorrent-1\.1)/,/^(?:CrystalStacker)/,/^(?:FLTK-exception)/,/^(?:SugarCRM-1\.1\.3)/,/^(?:BSD-Protection)/,/^(?:BitTorrent-1\.0)/,/^(?:HaskellReport)/,/^(?:Interbase-1\.0)/,/^(?:StandardML-NJ)/,/^(?:mif-exception)/,/^(?:Frameworx-1\.0)/,/^(?:389-exception)/,/^(?:CC-BY-NC-2\.0)/,/^(?:CC-BY-NC-2\.5)/,/^(?:CC-BY-NC-3\.0)/,/^(?:CC-BY-NC-4\.0)/,/^(?:W3C-19980720)/,/^(?:CC-BY-SA-1\.0)/,/^(?:CC-BY-SA-2\.0)/,/^(?:CC-BY-SA-2\.5)/,/^(?:CC-BY-ND-2\.0)/,/^(?:CC-BY-SA-4\.0)/,/^(?:CC-BY-SA-3\.0)/,/^(?:Artistic-1\.0)/,/^(?:Artistic-2\.0)/,/^(?:CC-BY-ND-2\.5)/,/^(?:CC-BY-ND-3\.0)/,/^(?:CC-BY-ND-4\.0)/,/^(?:CC-BY-ND-1\.0)/,/^(?:BSD-4-Clause)/,/^(?:BSD-3-Clause)/,/^(?:BSD-2-Clause)/,/^(?:CC-BY-NC-1\.0)/,/^(?:bzip2-1\.0\.6)/,/^(?:Unicode-TOU)/,/^(?:CNRI-Jython)/,/^(?:ImageMagick)/,/^(?:Adobe-Glyph)/,/^(?:CUA-OPL-1\.0)/,/^(?:OLDAP-2\.2\.2)/,/^(?:LiLiQ-R-1\.1)/,/^(?:bzip2-1\.0\.5)/,/^(?:LiLiQ-P-1\.1)/,/^(?:OLDAP-2\.0\.1)/,/^(?:OLDAP-2\.2\.1)/,/^(?:CNRI-Python)/,/^(?:XFree86-1\.1)/,/^(?:OSET-PL-2\.1)/,/^(?:Apache-2\.0)/,/^(?:Watcom-1\.0)/,/^(?:PostgreSQL)/,/^(?:Python-2\.0)/,/^(?:RHeCos-1\.1)/,/^(?:EUDatagrid)/,/^(?:Spencer-99)/,/^(?:Intel-ACPI)/,/^(?:CECILL-1\.0)/,/^(?:CECILL-1\.1)/,/^(?:JasPer-2\.0)/,/^(?:CECILL-2\.0)/,/^(?:CECILL-2\.1)/,/^(?:gSOAP-1\.3b)/,/^(?:Spencer-94)/,/^(?:Apache-1\.1)/,/^(?:Spencer-86)/,/^(?:Apache-1\.0)/,/^(?:ClArtistic)/,/^(?:TORQUE-1\.1)/,/^(?:CATOSL-1\.1)/,/^(?:Adobe-2006)/,/^(?:Zimbra-1\.4)/,/^(?:Zimbra-1\.3)/,/^(?:Condor-1\.1)/,/^(?:CC-BY-3\.0)/,/^(?:CC-BY-2\.5)/,/^(?:OLDAP-2\.4)/,/^(?:SGI-B-1\.1)/,/^(?:SISSL-1\.2)/,/^(?:SGI-B-1\.0)/,/^(?:OLDAP-2\.3)/,/^(?:CC-BY-4\.0)/,/^(?:Crossword)/,/^(?:SimPL-2\.0)/,/^(?:OLDAP-2\.2)/,/^(?:OLDAP-2\.1)/,/^(?:ErlPL-1\.1)/,/^(?:LPPL-1\.3a)/,/^(?:LPPL-1\.3c)/,/^(?:OLDAP-2\.0)/,/^(?:Leptonica)/,/^(?:CPOL-1\.02)/,/^(?:OLDAP-1\.4)/,/^(?:OLDAP-1\.3)/,/^(?:CC-BY-2\.0)/,/^(?:Unlicense)/,/^(?:OLDAP-2\.8)/,/^(?:OLDAP-1\.2)/,/^(?:MakeIndex)/,/^(?:OLDAP-2\.7)/,/^(?:OLDAP-1\.1)/,/^(?:Sleepycat)/,/^(?:D-FSL-1\.0)/,/^(?:CC-BY-1\.0)/,/^(?:OLDAP-2\.6)/,/^(?:WXwindows)/,/^(?:NPOSL-3\.0)/,/^(?:FreeImage)/,/^(?:SGI-B-2\.0)/,/^(?:OLDAP-2\.5)/,/^(?:Beerware)/,/^(?:Newsletr)/,/^(?:NBPL-1\.0)/,/^(?:NASA-1\.3)/,/^(?:NLOD-1\.0)/,/^(?:AGPL-1\.0)/,/^(?:OCLC-2\.0)/,/^(?:ODbL-1\.0)/,/^(?:PDDL-1\.0)/,/^(?:Motosoto)/,/^(?:Afmparse)/,/^(?:ANTLR-PD)/,/^(?:LPL-1\.02)/,/^(?:Abstyles)/,/^(?:eCos-2\.0)/,/^(?:APSL-1\.0)/,/^(?:LPPL-1\.2)/,/^(?:LPPL-1\.1)/,/^(?:LPPL-1\.0)/,/^(?:APSL-1\.1)/,/^(?:APSL-2\.0)/,/^(?:Info-ZIP)/,/^(?:Zend-2\.0)/,/^(?:IBM-pibs)/,/^(?:LGPL-2\.0)/,/^(?:LGPL-3\.0)/,/^(?:LGPL-2\.1)/,/^(?:GFDL-1\.3)/,/^(?:PHP-3\.01)/,/^(?:GFDL-1\.2)/,/^(?:GFDL-1\.1)/,/^(?:AGPL-3\.0)/,/^(?:Giftware)/,/^(?:EUPL-1\.1)/,/^(?:RPSL-1\.0)/,/^(?:EUPL-1\.0)/,/^(?:MIT-enna)/,/^(?:CECILL-B)/,/^(?:diffmark)/,/^(?:CECILL-C)/,/^(?:CDDL-1\.0)/,/^(?:Sendmail)/,/^(?:CDDL-1\.1)/,/^(?:CPAL-1\.0)/,/^(?:APSL-1\.2)/,/^(?:NPL-1\.1)/,/^(?:AFL-1\.2)/,/^(?:Caldera)/,/^(?:AFL-2\.0)/,/^(?:FSFULLR)/,/^(?:AFL-2\.1)/,/^(?:VSL-1\.0)/,/^(?:VOSTROM)/,/^(?:UPL-1\.0)/,/^(?:Dotseqn)/,/^(?:CPL-1\.0)/,/^(?:dvipdfm)/,/^(?:EPL-1\.0)/,/^(?:OCCT-PL)/,/^(?:ECL-1\.0)/,/^(?:Latex2e)/,/^(?:ECL-2\.0)/,/^(?:GPL-1\.0)/,/^(?:GPL-2\.0)/,/^(?:GPL-3\.0)/,/^(?:AFL-3\.0)/,/^(?:LAL-1\.2)/,/^(?:LAL-1\.3)/,/^(?:EFL-1\.0)/,/^(?:EFL-2\.0)/,/^(?:gnuplot)/,/^(?:Aladdin)/,/^(?:LPL-1\.0)/,/^(?:libtiff)/,/^(?:Entessa)/,/^(?:AMDPLPA)/,/^(?:IPL-1\.0)/,/^(?:OPL-1\.0)/,/^(?:OSL-1\.0)/,/^(?:OSL-1\.1)/,/^(?:OSL-2\.0)/,/^(?:OSL-2\.1)/,/^(?:OSL-3\.0)/,/^(?:OpenSSL)/,/^(?:ZPL-2\.1)/,/^(?:PHP-3\.0)/,/^(?:ZPL-2\.0)/,/^(?:ZPL-1\.1)/,/^(?:CC0-1\.0)/,/^(?:SPL-1\.0)/,/^(?:psutils)/,/^(?:MPL-1\.0)/,/^(?:QPL-1\.0)/,/^(?:MPL-1\.1)/,/^(?:MPL-2\.0)/,/^(?:APL-1\.0)/,/^(?:RPL-1\.1)/,/^(?:RPL-1\.5)/,/^(?:MIT-CMU)/,/^(?:Multics)/,/^(?:Eurosym)/,/^(?:BSL-1\.0)/,/^(?:MIT-feh)/,/^(?:Saxpath)/,/^(?:Borceux)/,/^(?:OFL-1\.1)/,/^(?:OFL-1\.0)/,/^(?:AFL-1\.1)/,/^(?:YPL-1\.1)/,/^(?:YPL-1\.0)/,/^(?:NPL-1\.0)/,/^(?:iMatix)/,/^(?:mpich2)/,/^(?:APAFML)/,/^(?:Bahyph)/,/^(?:RSA-MD)/,/^(?:psfrag)/,/^(?:Plexus)/,/^(?:eGenix)/,/^(?:Glulxe)/,/^(?:SAX-PD)/,/^(?:Imlib2)/,/^(?:Wsuipa)/,/^(?:LGPLLR)/,/^(?:Libpng)/,/^(?:xinetd)/,/^(?:MITNFA)/,/^(?:NetCDF)/,/^(?:Naumen)/,/^(?:SMPPL)/,/^(?:Nunit)/,/^(?:FSFUL)/,/^(?:GL2PS)/,/^(?:SMLNJ)/,/^(?:Rdisc)/,/^(?:Noweb)/,/^(?:Nokia)/,/^(?:SISSL)/,/^(?:Qhull)/,/^(?:Intel)/,/^(?:Glide)/,/^(?:Xerox)/,/^(?:AMPAS)/,/^(?:WTFPL)/,/^(?:MS-PL)/,/^(?:XSkat)/,/^(?:MS-RL)/,/^(?:MirOS)/,/^(?:RSCPL)/,/^(?:TMate)/,/^(?:OGTSL)/,/^(?:FSFAP)/,/^(?:NCSA)/,/^(?:Zlib)/,/^(?:SCEA)/,/^(?:SNIA)/,/^(?:NGPL)/,/^(?:NOSL)/,/^(?:ADSL)/,/^(?:MTLL)/,/^(?:NLPL)/,/^(?:Ruby)/,/^(?:JSON)/,/^(?:Barr)/,/^(?:0BSD)/,/^(?:Xnet)/,/^(?:Cube)/,/^(?:curl)/,/^(?:DSDP)/,/^(?:Fair)/,/^(?:HPND)/,/^(?:TOSL)/,/^(?:IJG)/,/^(?:SWL)/,/^(?:Vim)/,/^(?:FTL)/,/^(?:ICU)/,/^(?:OML)/,/^(?:NRL)/,/^(?:DOC)/,/^(?:TCL)/,/^(?:W3C)/,/^(?:NTP)/,/^(?:IPA)/,/^(?:ISC)/,/^(?:X11)/,/^(?:AAL)/,/^(?:AML)/,/^(?:xpp)/,/^(?:Zed)/,/^(?:MIT)/,/^(?:Mup)/],
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,362,363,364],"inclusive":true}}
});
return lexer;
})();
parser.lexer = lexer;
function Parser () {
this.yy = {};
}
Parser.prototype = parser;parser.Parser = Parser;
return new Parser;
})();
Eif (typeof require !== 'undefined' && typeof exports !== 'undefined') {
exports.parser = spdxparse;
exports.Parser = spdxparse.Parser;
exports.parse = function () { return spdxparse.parse.apply(spdxparse, arguments); };
exports.main = function commonjsMain(args) {
if (!args[1]) {
console.log('Usage: '+args[0]+' FILE');
process.exit(1);
}
var source = require('fs').readFileSync(require('path').normalize(args[1]), "utf8");
return exports.parser.parse(source);
};
Iif (typeof module !== 'undefined' && require.main === module) {
exports.main(process.argv.slice(1));
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 28.57% | (2 / 7) | 0% | (0 / 11) | 0% | (0 / 1) | 28.57% | (2 / 7) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 1 1 | 'use strict';
var isUtf8 = require('is-utf8');
module.exports = function (x) {
// Catches EFBBBF (UTF-8 BOM) because the buffer-to-string
// conversion translates it to FEFF (UTF-16 BOM)
if (typeof x === 'string' && x.charCodeAt(0) === 0xFEFF) {
return x.slice(1);
}
if (Buffer.isBuffer(x) && isUtf8(x) &&
x[0] === 0xEF && x[1] === 0xBB && x[2] === 0xBF) {
return x.slice(3);
}
return x;
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 26.42% | (14 / 53) | 0% | (0 / 41) | 0% | (0 / 8) | 28.57% | (14 / 49) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | const assign = require('object-assign')
const arrify = require('arrify')
const micromatch = require('micromatch')
const path = require('path')
const readPkgUp = require('read-pkg-up')
const requireMainFilename = require('require-main-filename')
function TestExclude (opts) {
assign(this, {
cwd: process.cwd(),
include: false,
configKey: null, // the key to load config from in package.json.
configPath: null, // optionally override requireMainFilename.
configFound: false
}, opts)
if (typeof this.include === 'string') this.include = [this.include]
if (typeof this.exclude === 'string') this.exclude = [this.exclude]
if (!this.include && !this.exclude && this.configKey) {
assign(this, this.pkgConf(this.configKey, this.configPath))
}
if (!this.exclude || !Array.isArray(this.exclude)) {
this.exclude = exportFunc.defaultExclude
}
if (this.include && this.include.length > 0) {
this.include = prepGlobPatterns(arrify(this.include))
} else {
this.include = false
}
if (!this.removeNegatedModuleExclude() && this.exclude.indexOf('**/node_modules/**') === -1) {
this.exclude.push('**/node_modules/**')
}
this.exclude = prepGlobPatterns(
[].concat(arrify(this.exclude))
)
}
// if a glob has been provided that explicitly negates
// the **/node_modules/** default exclude rule, remove it from
// excludes but don't add the default exclude rule.
TestExclude.prototype.removeNegatedModuleExclude = function () {
var moduleExcludeNegated = false
this.exclude = this.exclude.filter(function (e) {
var negated = !!micromatch('./node_modules/foo.js', e, {nonegate: false}).length !==
!!micromatch('./node_modules/foo.js', e, {nonegate: true}).length
if (negated) moduleExcludeNegated = true
return !negated
})
return moduleExcludeNegated
}
TestExclude.prototype.shouldInstrument = function (filename, relFile) {
relFile = relFile || path.relative(this.cwd, filename)
// Don't instrument files that are outside of the current working directory.
if (/^\.\./.test(path.relative(this.cwd, filename))) return false
relFile = relFile.replace(/^\.[\\/]/, '') // remove leading './' or '.\'.
return (!this.include || micromatch.any(relFile, this.include, {dotfiles: true})) && !micromatch.any(relFile, this.exclude, {dotfiles: true})
}
TestExclude.prototype.pkgConf = function (key, path) {
const obj = readPkgUp.sync({
cwd: path || requireMainFilename(require)
})
if (obj.pkg && obj.pkg[key] && typeof obj.pkg[key] === 'object') {
this.configFound = true
return obj.pkg[key]
} else {
return {}
}
}
function prepGlobPatterns (patterns) {
return patterns.reduce(function (result, pattern) {
// Allow gitignore style of directory exclusion
if (!/\/\*\*$/.test(pattern)) {
result = result.concat(pattern.replace(/\/$/, '') + '/**')
}
// Any rules of the form **/foo.js, should also match foo.js.
if (/^\*\*\//.test(pattern)) {
result = result.concat(pattern.replace(/^\*\*\//, ''))
}
return result.concat(pattern)
}, [])
}
var exportFunc = function (opts) {
return new TestExclude(opts)
}
exportFunc.defaultExclude = [
'coverage/**',
'test/**',
'test{,-*}.js',
'**/*.test.js',
'**/__tests__/**',
'**/node_modules/**'
]
module.exports = exportFunc
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 25% | (7 / 28) | 0% | (0 / 16) | 0% | (0 / 3) | 25% | (7 / 28) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 1 1 1 1 1 1 1 | var parse = require('spdx-expression-parse');
var correct = require('spdx-correct');
var genericWarning = (
'license should be ' +
'a valid SPDX license expression (without "LicenseRef"), ' +
'"UNLICENSED", or ' +
'"SEE LICENSE IN <filename>"'
);
var fileReferenceRE = /^SEE LICEN[CS]E IN (.+)$/;
function startsWith(prefix, string) {
return string.slice(0, prefix.length) === prefix;
}
function usesLicenseRef(ast) {
if (ast.hasOwnProperty('license')) {
var license = ast.license;
return (
startsWith('LicenseRef', license) ||
startsWith('DocumentRef', license)
);
} else {
return (
usesLicenseRef(ast.left) ||
usesLicenseRef(ast.right)
);
}
}
module.exports = function(argument) {
var ast;
try {
ast = parse(argument);
} catch (e) {
var match
if (
argument === 'UNLICENSED' ||
argument === 'UNLICENCED'
) {
return {
validForOldPackages: true,
validForNewPackages: true,
unlicensed: true
};
} else if (match = fileReferenceRE.exec(argument)) {
return {
validForOldPackages: true,
validForNewPackages: true,
inFile: match[1]
};
} else {
var result = {
validForOldPackages: false,
validForNewPackages: false,
warnings: [genericWarning]
};
var corrected = correct(argument);
if (corrected) {
result.warnings.push(
'license is similar to the valid expression "' + corrected + '"'
);
}
return result;
}
}
if (usesLicenseRef(ast)) {
return {
validForNewPackages: false,
validForOldPackages: false,
spdx: true,
warnings: [genericWarning]
};
} else {
return {
validForNewPackages: true,
validForOldPackages: true,
spdx: true
};
}
};
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| wrappy.js | 36.84% | (7 / 19) | 40% | (4 / 10) | 25% | (1 / 4) | 38.89% | (7 / 18) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 1 1 3 3 3 3 1 | // Returns a wrapper function that returns a wrapped callback
// The wrapper function should do some stuff, and return a
// presumably different callback function.
// This makes sure that own properties are retained, so that
// decorations and such are not lost along the way.
module.exports = wrappy
function wrappy (fn, cb) {
Iif (fn && cb) return wrappy(fn)(cb)
Iif (typeof fn !== 'function')
throw new TypeError('need wrapper function')
Object.keys(fn).forEach(function (k) {
wrapper[k] = fn[k]
})
return wrapper
function wrapper() {
var args = new Array(arguments.length)
for (var i = 0; i < args.length; i++) {
args[i] = arguments[i]
}
var ret = fn.apply(this, args)
var cb = args[args.length-1]
if (typeof ret === 'function' && ret !== cb) {
Object.keys(cb).forEach(function (k) {
ret[k] = cb[k]
})
}
return ret
}
}
|
| File | Statements | Branches | Functions | Lines | |||||
|---|---|---|---|---|---|---|---|---|---|
| index.js | 22.03% | (13 / 59) | 2.08% | (1 / 48) | 0% | (0 / 9) | 25% | (13 / 52) |
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 1 1 1 1 1 1 1 1 1 1 1 1 1 | 'use strict'
module.exports = writeFile
module.exports.sync = writeFileSync
module.exports._getTmpname = getTmpname // for testing
var fs = require('graceful-fs')
var chain = require('slide').chain
var MurmurHash3 = require('imurmurhash')
var extend = Object.assign || require('util')._extend
var invocations = 0
function getTmpname (filename) {
return filename + '.' +
MurmurHash3(__filename)
.hash(String(process.pid))
.hash(String(++invocations))
.result()
}
function writeFile (filename, data, options, callback) {
if (options instanceof Function) {
callback = options
options = null
}
if (!options) options = {}
fs.realpath(filename, function (_, realname) {
_writeFile(realname || filename, data, options, callback)
})
}
function _writeFile (filename, data, options, callback) {
var tmpfile = getTmpname(filename)
if (options.mode && options.chown) {
return thenWriteFile()
} else {
// Either mode or chown is not explicitly set
// Default behavior is to copy it from original file
return fs.stat(filename, function (err, stats) {
if (err || !stats) return thenWriteFile()
options = extend({}, options)
if (!options.mode) {
options.mode = stats.mode
}
if (!options.chown && process.getuid) {
options.chown = { uid: stats.uid, gid: stats.gid }
}
return thenWriteFile()
})
}
function thenWriteFile () {
chain([
[fs, fs.writeFile, tmpfile, data, options.encoding || 'utf8'],
options.mode && [fs, fs.chmod, tmpfile, options.mode],
options.chown && [fs, fs.chown, tmpfile, options.chown.uid, options.chown.gid],
[fs, fs.rename, tmpfile, filename]
], function (err) {
err ? fs.unlink(tmpfile, function () { callback(err) })
: callback()
})
}
}
function writeFileSync (filename, data, options) {
if (!options) options = {}
try {
filename = fs.realpathSync(filename)
} catch (ex) {
// it's ok, it'll happen on a not yet existing file
}
var tmpfile = getTmpname(filename)
try {
if (!options.mode || !options.chown) {
// Either mode or chown is not explicitly set
// Default behavior is to copy it from original file
try {
var stats = fs.statSync(filename)
options = extend({}, options)
if (!options.mode) {
options.mode = stats.mode
}
if (!options.chown && process.getuid) {
options.chown = { uid: stats.uid, gid: stats.gid }
}
} catch (ex) {
// ignore stat errors
}
}
fs.writeFileSync(tmpfile, data, options.encoding || 'utf8')
if (options.chown) fs.chownSync(tmpfile, options.chown.uid, options.chown.gid)
if (options.mode) fs.chmodSync(tmpfile, options.mode)
fs.renameSync(tmpfile, filename)
} catch (err) {
try { fs.unlinkSync(tmpfile) } catch (e) {}
throw err
}
}
|